所以我有一个疯狂的想法,我想将一个范围应用于一个包含的协会。这就是我想到的,它似乎工作正常:
class Event < ActiveRecord::Base
has_many :races
has_many :bad_races, :conditions => Race.bad_medals_sql, :class_name => "Race"
end
class Race < ActiveRecord::Base
def self.bad_medals_sql
arel_table[:prizes].eq('medals').to_sql
# This returns a string
# "`races`.`prizes` = 'medals'"
end
def self.bad_medals
where(bad_medals_sql)
end
end
Event.includes(:bad_races)
Reloading...
Event Load (0.4ms) SELECT `events`.* FROM `events`
Race Load (0.5ms) SELECT `races`.* FROM `races` WHERE (`races`.event_id IN (1,2,3,4) AND (`races`.`prizes` = 'medals'))
问题在于它真的很钝。为了在Race上定义范围(在别处使用)并在Event的关联上使用它,我必须在Race上有两个方法。对于每个范围。
我确信我可以将模式包装成插件或其他一些插件,但如果可能的话,我宁愿使用原生AR / ARel。有没有这样做的想法?
答案 0 :(得分:6)
这段代码看起来过于复杂。假设您的目标是让所有包含仅有“奖牌”的比赛的活动用于奖品,那么简单的scope
是否有效?
class Event < ActiveRecord::Base
has_many :races
scope :bad_races, includes(:races).where("races.prizes=?", "medals")
end
class Race < ActiveRecord::Base
belongs_to :event
end
然后你可以运行Event.bad_races
来获得糟糕的比赛。
答案 1 :(得分:0)
表达关联范围的最新方式如下:
scope :bad_races, -> { joins(:races).where(races: { prizes: 'medals' }) }
答案 2 :(得分:0)
您可以使用merge方法在两个模型上使用范围。在这种情况下它非常方便:
class Event < ActiveRecord::Base
has_many :races
scope :bad_races, -> { joins(:races).merge(Race.bad_medals) }
end
class Race < ActiveRecord::Base
belongs_to :event
scope :bad_medals, -> { where(price: 'medal') }
end