我有一个树状模型,在所有情况但只有一个中,我想将结果范围仅返回根。
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
非常合理。< / p>
那么有什么好方法可以解决这个具体问题吗?
这是我不太喜欢的一个,因为它使用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()
进行每个查询都不是很干,说实话。它只是要求在不使用范围的情况下发生错误。
答案 0 :(得分:2)
尝试使用Licence.unscoped.find()
ActiveRecord::Base.unscoped
的文档说明使用命名unscoped
方法链接scope
无效。unscoped
的阻止形式,因为将unscoped
与名为scope
的链接不起作用。如果“sent”(下面)是named_scope,则以下两个语句是相同的。
Message.unscoped.sent
Message.sent
fyi rails 2也有with_exclusive_scope
,这可能会有所帮助。
答案 1 :(得分:0)
你不能在关联中使用:conditions
选项吗?像这样:
has_many :nested_licences, :class_name => 'Licence',
:dependent => :destroy, :conditions => "parent_licence_id = #{id}"