Уровень слишком глубокой ошибки в Ruby on Rails
У меня слишком высокий уровень стека с использованием Ruby 1.8.7 с Rails
3.0.4 и с консолью rails я выполнил следующие команды.
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'
Вот объект, который имеет проблемы.
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
Ответы
Ответ 1
Я нашел решение этой проблемы...
Я использую Rails 3, и мой класс выглядит так (и проблемные методы тоже были)
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
Мне пришлось много взломать код, чтобы узнать, что что-то не так с named_scope в строке
@organizations = self.find :all, :conditions => ['is_company = ? ',true]
Поэтому мне пришлось изменить его на что-то вроде этого
@organizations = Organization.where("is_company = ?",true)
Но это тоже было неправильно. Поэтому я решил добавить область для этого ниже имени класса, чтобы конечный код выглядел следующим образом:
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
Итак, используя эту строку с областью
@organizations = self.company
он работал безупречно в каждой части кода.
Мне было интересно, если named_scope устарел при использовании методов класса или они не поддерживаются с этого момента и выдает ошибку, а не предупреждение перед
Спасибо за вашу помощь
Лео
Ответ 2
Эта ошибка обычно возникает при случайном рекурсивном изменении атрибута. Если у вас есть атрибут имени пользователя в модели User и виртуальный атрибут с именем пользователя, который напрямую меняет имя пользователя, вы в конечном итоге вызываете виртуальный, виртуальный снова вызывает виртуальную машину и т.д. Поэтому посмотрите, что-то как это происходит где-то в вашем коде.
Ответ 3
Также возникает ошибка уровня стека слишком глубокая, если вы хотите уничтожить запись, и у вас есть связь с :dependent => :destroy
с другой моделью. Если другая модель имеет связь с :dependent => :destroy
назад к этой модели, уровень уровня слишком глубокий.
Ответ 4
У меня была проблема "stack-level too deep"
. это было вызвано рекурсивностью в одной из моих функций и было вызвано опечаткой, как вы можете видеть снизу:
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
Я понял, что мне пришлось изменить вторую строчку на зашифрованную, и она сработала. Просто проверьте, чтобы рекурсия в коде была где-то. К сожалению, я не могу быть более полезным, так как я не могу смотреть на все ваши файлы кода.
Ответ 5
Поскольку вы не показываете весь код, я могу только предположить, что вы определили inspect
или to_s
, чтобы построить строку, содержащую, помимо прочего, родителей.
Ваш текущий метод parents
, похоже, не делает ничего разумного, так как он возвращает все организации, которые являются компаниями, независимо от того, с какой ассоциации вы начинаете. Таким образом, любая компания сама по себе является родителем. Попытка конвертировать его в строку вызовет бесконечный цикл, чтобы попытаться показать родителям родителей...
В любом случае основная часть вашего метода parents
должна быть в помощнике, называемом чем-то вроде options_for_parents_select
, потому что это то, что она делает? Даже тогда первый пустой выбор должен быть передан как allow_null
для выбора.
Тот факт, что он задает переменные экземпляра, является запахом кода.
Удачи.
Ответ 6
Я получал такой же уровень стека слишком глубокий, и выяснилось, что проблема заключалась в повторном рендеринге частичного.
Мне пришлось вызвать render a_partial в главном представлении, а затем в частичном, я случайно назвал тот же частичный снова.
НТН
Ответ 7
Если вы получаете эту ошибку, это означает, что версия rails, которую вы используете в своем приложении, несовместима с версией Ruby.
Решения, которые вы можете использовать для решения этой проблемы.
1) Вам нужно понизить версию ruby до более старой версии.
2) или вам необходимо обновить Rails до последней версии.