Подтвердить что ты не робот

Уровень слишком глубокой ошибки в 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
4b9b3361

Ответ 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 до последней версии.