2

我有一个树状模型,在除一种之外的所有情况下,我都希望将结果范围限定为仅返回根。

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_scope似乎是一个很棒的想法,因为与许可证关联的各种模型(大约有 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

但这真的不是很干。Licence.roots.find()老实说,实际上必须通过而不是做每一个查询Licence.find()也不是很干。它只是要求在不使用范围的地方发生错误。

4

2 回答 2

2

尝试使用Licence.unscoped.find()

btw - The documentation for ActiveRecord::Base.unscoped says that chaining unscoped with a named scope method has no effect.
It is recommended to use the block form of unscoped because chaining unscoped with a named scope does not work. If "sent" (below) is a named_scope the following two statements are the same.

Message.unscoped.sent
Message.sent  

fyi rails 2 also has with_exclusive_scope which can be helpful.

于 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 回答