【发布时间】:2012-07-24 17:53:20
【问题描述】:
假设我有以下课程
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 关系,以便当我为所有关联的planets 询问solar_system 时,会自动应用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.planets 的任何地方使用solar_system.life_supporting_planets。
都没有回答这个问题,所以我只是把它们放在这里,以防其他人遇到这种情况。
【问题讨论】:
-
使用 where_vales 的解决方法确实是最好的解决方案,值得接受的答案
-
where_values可能不适用于散列条件:{:cleared => false}...它提供了 ActiveRecord 不喜欢的散列数组。作为 hack,抓取数组中的第一项是有效的:Planet.life_supporting.where_values[0]... -
我发现我必须使用
where_ast而不是where_values或where_values_hash,因为我在其他型号的范围内使用了 AREL。工作了一个款待! +1
标签: ruby-on-rails-3 activerecord has-many