J'ai une erreur de niveau de pile trop profonde en utilisant Ruby 1.8.7 avec Rails 3.0.4 et avec le Rails = console J'ai exécuté les commandes suivantes.
leo%>Rails console
Loading development environment (Rails 3.0.4)
Ruby-1.8.7-head > leo = Organization.find(1)
SystemStackError: stack level too deep
from /app/models/organization.rb:105:in `parents'
Voici l'objet qui a des problèmes ..
class Organization < ActiveRecord::Base
has_many :group_organizations, :dependent =>
:delete_all
has_many :groups, :through => :group_organizations
has_many :orders
has_many :product_contracts
has_many :people
accepts_nested_attributes_for :people
has_many :addresses
accepts_nested_attributes_for :addresses
has_many :organizations
has_many :departments
has_many :organization_credits
has_many :documents
validates_presence_of :name
def self.parents
@organizations = Organization.where("is_company = ?",true)
#@organization_parents = []
select_choice = I18n.t("select") + " "+ I18n.t("segments.description")
@organization_parents = [select_choice]
for organization in @organizations
@organization_parents << [organization.name, organization.id]
end
return @organization_parents
end
J'ai trouvé la solution à ce problème ...
J'utilise Rails 3 et ma classe ressemble à ceci (et les méthodes problématiques l'étaient aussi)
class Organization < ActiveRecord::Base
def self.parents
@organizations = self.find :all, :conditions => ['is_company = ? ',true]
select_choice = I18n.t("select") + " "+ I18n.t("segments.description")
@organization_parents = [select_choice]
for organization in @organizations
@organization_parents << [organization.name, organization.id]
end
return @organization_parents
end
#...
end
J'ai dû pirater beaucoup dans le code pour découvrir que quelque chose n'allait pas avec le named_scope sur la ligne
@organizations = self.find :all, :conditions => ['is_company = ? ',true]
J'ai donc dû le changer en quelque chose comme ça
@organizations = Organization.where("is_company = ?",true)
Mais c'était faux aussi .. J'ai donc décidé d'ajouter une portée pour cela sous le nom de la classe pour que le code final ressemble à ceci:
class Organization < ActiveRecord::Base
scope :company, where("is_company = ?",true)
def self.parents
@organizations = self.company
select_choice = I18n.t("select") + " "+ I18n.t("segments.description")
@organization_parents = [select_choice]
for organization in @organizations
@organization_parents << [organization.name, organization.id]
end
return @organization_parents
end
#...
end
Donc, en utilisant cette ligne avec la portée
@organizations = self.company
cela a fonctionné parfaitement dans chaque partie du code.
Je me demandais si le named_scope est obsolète lors de l'utilisation de méthodes de classe ou s'ils ne sont pas pris en charge à partir de maintenant et génère une erreur et pas un avertissement avant
Merci pour votre aide Leo
Cette erreur se produit généralement lorsque vous modifiez accidentellement et récursivement un attribut. Si vous avez un attribut de nom d'utilisateur dans le modèle utilisateur et un attribut virtuel nommé nom d'utilisateur, qui modifie directement le nom d'utilisateur, vous finissez par appeler le virtuel, le virtuel appelle à nouveau le virtuel et ainsi de suite. Par conséquent, vérifiez si quelque chose comme ça arrive quelque part dans votre code.
L'erreur niveau de pile trop profond se produit également si vous voulez détruire un enregistrement et que vous avez une association avec :dependent => :destroy
vers un autre modèle. Si l'autre modèle est associé à :dependent => :destroy
de retour à ce modèle, le le niveau de la pile est trop profond, aussi.
J'ai eu un "stack-level too deep"
problème aussi. cela était dû à la récursivité de l'une de mes fonctions et avait été causé par une faute de frappe comme vous pouvez le voir ci-dessous:
def has_password?(submitted_password)
encrypt_password == encrypt(submitted_password)
end
private
def encrypt_password
self.salt = make_salt unless has_password?(password)
self.encrypted_password = encrypt(password)
end
J'ai réalisé que je devais changer la deuxième ligne en crypté et cela a fonctionné. Vérifiez simplement la récursivité dans votre code, cela doit se produire quelque part. Malheureusement, je ne peux pas être mieux utilisé car je ne peux pas regarder tous vos fichiers de code.
J'obtenais la même chose niveau de pile trop profond erreur et il s'avère que le problème était le rendu récurrent d'un partiel.
Il m'est arrivé d'appeler render a_partial dans la vue principale, puis dans le partiel, j'ai accidentellement appelé à nouveau le même partiel.
HTH
Si vous obtenez cette erreur, cela signifie Rails que vous utilisez dans votre application n'est pas compatible avec la version Ruby Version.
Solutions que vous pouvez utiliser pour résoudre ce problème.
1) Vous devez rétrograder la version Ruby vers une version plus ancienne).
2) ou vous devez mettre à niveau Rails vers la dernière version.
Comme vous ne montrez pas tout le code, je ne peux que spéculer que vous avez défini inspect
ou to_s
pour construire une chaîne contenant, entre autres, les parents.
Votre méthode parents
actuelle ne semble pas faire quoi que ce soit de raisonnable, car elle renvoie toutes les organisations qui sont des entreprises, quelle que soit l'association à partir de laquelle vous commencez. Ainsi, toute entreprise a elle-même comme société mère. Tenter de le convertir en chaîne induira une boucle infinie pour essayer de montrer les parents des parents de ...
Dans tous les cas, la majeure partie de votre méthode parents
doit être dans un assistant, appelé quelque chose comme options_for_parents_select
, parce que c'est ce qu'il semble faire? Même alors, le premier choix vide doit être passé comme allow_null
pour sélectionner.
Le fait qu'il définit des variables d'instance est une odeur de code.
Bonne chance