So I got this crazy idea that I wanted to apply a scope to an included association. This is what I figured out, and it seems to work just fine:
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'))
The problem is that it's really obtuse. In order to have the scope defined on Race (to use elsewhere) and to use it on the Event's association I have to have two methods on Race. For each scope.
I'm sure that I could wrap the pattern into a plugin or some such, but I'd much rather use native AR/ARel if that's possible. Any ideas for doing that?
This code seems overly complex. Assuming that your goal is to get all the events that contain races with only "medals" for prizes, wouldn't a simple scope
work?
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
Then you can just run Event.bad_races
to get the bad races.
You can use scopes on both models with merge method. It's really handy in this case:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With