默认在Rails has_many关系上使用范围 [英] Use a scope by default on a Rails has_many relationship
问题描述
假设我有以下课程
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(请参见 ActiveRecord :: Associ ations :: ClassMethods )
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关系上使用范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!