2

私はツリーのようなモデルを持っていますが、1 つを除くすべての状況で、ルートのみを返すように結果をスコープしたいと考えています。

class Licence < ActiveRecord::Base
  default_scope :conditions => { :parent_licence_id, nil }

  belongs_to :parent_licence, :class_name => 'Licence'
  has_many :nested_licences, :class_name => 'Licence',
           :foreign_key => 'parent_licence_id', :dependent => :destroy
end

class User < ActiveRecord::Base
  has_many :licences
end

default_scopeLicense に関連付けられているさまざまなモデル (約 4 つあります) と、find() を使用するコードは特別なことをする必要がないため、使用は素晴らしいアイデアのように思えました。これが素晴らしいアイデアではない理由は、デフォルトのスコープが にも適用されhas_many、その結果、子が見つからないためです。しかし、これは範囲外にする必要has_manyがある唯一の場所なので、「デフォルト」の動作に関する限り、これdefault_scopeは非常に合理的だと思います。

では、この特定の問題を回避する良い方法はありますか?

これは、ほとんど些細なクエリに SQL を使用するため、私があまり好きではないものです。

has_many :nested_licences, :class_name => 'Licence', :dependent => :destroy,
  :finder_sql => 'SELECT l.* FROM licences l WHERE l.parent_licence_id = #{id}',
  :counter_sql => 'SELECT COUNT(l.*) FROM licences l WHERE l.parent_licence_id = #{id}'

または、名前付きスコープをモデルからの関連付けに適用する方法はありますか? たとえば、このナンセンスコードの行に沿った何か:

class Licence < ActiveRecord::Base
  named_scope :roots, :conditions => { :parent_licence_id, nil }

  belongs_to :parent_licence, :class_name => 'Licence'
  has_many :nested_licences, :class_name => 'Licence',
           :foreign_key => 'parent_licence_id', :dependent => :destroy
end

class User < ActiveRecord::Base
  has_many :licences, :scope => :roots   # a :scope option doesn't really exist
end

私もこれを行うことができることを知っています:

class Licence < ActiveRecord::Base
  named_scope :roots, :conditions => { :parent_licence_id, nil }

  belongs_to :parent_licence, :class_name => 'Licence'
  has_many :nested_licences, :class_name => 'Licence',
           :foreign_key => 'parent_licence_id', :dependent => :destroy
end

class User < ActiveRecord::Base
  has_many :licences, :conditions => { :parent_licence_id, nil }
end

しかし、それは実際にはあまり DRY ではありません。正直に言うと、実際にすべてのクエリを実行するLicence.roots.find()代わりに、Licence.find()それほど DRY ではありません。スコープが使用されていない場所でバグが発生することを求めているだけです。

4

2 に答える 2

2

使ってみてLicence.unscoped.find()

ところで - のドキュメントには、名前付きメソッドによるActiveRecord::Base.unscoped連鎖は効果がないと書かれています。名前付きの連鎖は機能しないため 、ブロック形式を使用することをお勧めします。"sent" (以下) が named_scope の場合、次の 2 つのステートメントは同じです。unscopedscope
unscopedunscopedscope

Message.unscoped.sent
Message.sent  

fyi rails 2 にもwith_exclusive_scope役立つものがあります。

于 2011-10-19T20:07:51.663 に答える
0

:conditions協会のオプションを利用できないのですか?このようなもの:

has_many :nested_licences, :class_name => 'Licence',
         :dependent => :destroy, :conditions => "parent_licence_id = #{id}" 
于 2010-07-07T08:38:54.700 に答える