问题描述
假设我有以下课程
class SolarSystem < ActiveRecord::Base
has_many :planets
end
class Planet < ActiveRecord::Base
scope :life_supporting, where('distance_from_sun > ?', 5).order('diameter ASC')
end
行星
的范围为 life_supporting
和 SolarSystem
has_many:planets
。我想定义我的has_many关系,以便当我向所有关联的行星
询问 solar_system
时, life_supporting
范围会自动应用。本质上,我想要 solar_system.planets == solar_system.planets.life_supporting
。
Planet
has a scope life_supporting
and SolarSystem
has_many :planets
. I would like to define my has_many relationship so that when I ask a solar_system
for all associated planets
, the life_supporting
scope is automatically applied. Essentially, I would like solar_system.planets == solar_system.planets.life_supporting
.
-
我不是不要更改
scope:life_supporting
行星
到
default_scope其中('distance_from_sun>?',5).order (直径ASC)
我也想通过不必添加到 SolarSystem
I'd also like to prevent duplication by not having to add to SolarSystem
has_many:planets,:conditions => [’distance_from_sun> ?’,5],:order => '直径ASC'
我想拥有类似的东西
has_many:planets,:with_scope => :life_supporting
如@phoet所说,可能使用ActiveRecord无法实现默认范围。但是,我发现了两个潜在的解决方法。两者都防止重复。第一个虽然很长,但仍保持明显的可读性和透明性,第二个是输出清晰的辅助类型方法。
As @phoet said, it may not be possible to achieve a default scope using ActiveRecord. However, I have found two potential work arounds. Both prevent duplication. The first one, while long, maintains obvious readability and transparency, and the second one is a helper type method who's output is explicit.
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
Another solution which is a lot cleaner is to simply add the following method to SolarSystem
def life_supporting_planets
planets.life_supporting
end
并在任何要使用 solar_system.planets
solar_system.life_supporting_planets >。
and to use solar_system.life_supporting_planets
wherever you'd use solar_system.planets
.
都没有回答这个问题,所以我只是把它们放在这里,以防其他任何人遇到这种情况。
Neither answers the question so I just put them here as work arounds should anyone else encounter this situation.
推荐答案
在Rails 4中,关联
有一个可选的 scope
参数,该参数接受应用于 Relation
的lambda(请参见)
In Rails 4, Associations
have an optional scope
parameter that accepts a lambda that is applied to the Relation
(cf. the doc for 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_hash
处理更好的作用域来改进 where_values
解决方法条件由多个其中
或哈希(此处不是这种情况)定义。
In Rails 3, the where_values
workaround can sometimes be improved by using where_values_hash
that handles better scopes where conditions are defined by multiple where
or by a hash (not the case here).
has_many :planets, conditions: Planet.life_supporting.where_values_hash
这篇关于默认在Rails has_many关系上使用范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!