1. ホーム
  2. ruby-on-rails

[解決済み] Ruby on RailsでStack level too deepエラー発生

2022-02-19 22:09:52

質問

Ruby 1.8.7とRailsの組み合わせで、スタックレベルが深すぎるというエラーが発生します。 3.0.4で、rails consoleで以下のコマンドを実行しました。

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

解決方法は?

この問題の解決策を見つけたのですが...。

私は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は非推奨なのか、それとも今後はサポートされず、以前は警告ではなくエラーを投げていたのか、気になりました

ありがとうございました。 レオ