假设我有以下类(class)
class SolarSystem < ActiveRecord::Base
has_many :planets
end
class Planet < ActiveRecord::Base
scope :life_supporting, where('distance_from_sun > ?', 5).order('diameter ASC')
end
Planet
的作用域为life_supporting
和SolarSystem
has_many :planets
。我想定义我的has_many关系,以便当我向所有关联的solar_system
询问planets
时,会自动应用life_supporting
范围。本质上,我想要solar_system.planets == solar_system.planets.life_supporting
。要求
scope :life_supporting
中的Planet
为default_scope where('distance_from_sun > ?', 5).order('diameter ASC')
SolarSystem
来防止重复has_many :planets, :conditions => ['distance_from_sun > ?', 5], :order => 'diameter ASC'
目标
我想吃点类似的东西
has_many :planets, :with_scope => :life_supporting
编辑:变通正如@phoet所说,使用ActiveRecord可能无法实现默认范围。但是,我发现了两个潜在的解决方法。两者都防止重复。第一个虽然很长,但仍保持明显的可读性和透明性,第二个是帮助程序类型的方法,其输出是显式的。
class SolarSystem < ActiveRecord::Base
has_many :planets, :conditions => Planet.life_supporting.where_values,
:order => Planet.life_supporting.order_values
end
class Planet < ActiveRecord::Base
scope :life_supporting, where('distance_from_sun > ?', 5).order('diameter ASC')
end
另一个更清洁的解决方案是将以下方法简单地添加到SolarSystem
def life_supporting_planets
planets.life_supporting
end
并在需要使用solar_system.life_supporting_planets
的任何地方使用solar_system.planets
。两者均未回答问题,因此如果有人遇到这种情况,我将它们放在此处作为解决方法。
最佳答案
在Rails 4中,Associations
具有可选的scope
参数,该参数接受应用于Relation
的lambda(请参阅ActiveRecord::Associations::ClassMethods的文档)
class SolarSystem < ActiveRecord::Base
has_many :planets, -> { life_supporting }
end
class Planet < ActiveRecord::Base
scope :life_supporting, -> { where('distance_from_sun > ?', 5).order('diameter ASC') }
end
在Rails 3中,有时可以通过使用
where_values
来改进where_values_hash
的解决方法,该方法可以更好地处理由多个where
或哈希定义条件的范围(此处不是这种情况)。has_many :planets, conditions: Planet.life_supporting.where_values_hash
关于ruby-on-rails-3 - 默认在Rails has_many关系上使用范围,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11636541/