How can I use activerecord's query interface and scopes to identify the favorite in a race
I have two models Starter and Race.
Starter belongs_to :race Race has_many :starters
The attributes for Starter and race follow:
- Undefined class/module in ruby on rails
- Is it possible to run a single test in MiniTest?
- accepts_nested_attributes not saving any changes
- How to use CanCanCan with enum field?
- Rails doesn't convert timezone (PostgreSQL)
Starter attributes: id, race_id, finish_position, odds Race: id, race_date, race_number, field_size
I’m trying to accomplish two things:
- Select the favorite in each race. #for a particular race the Starter with the lowest odds*
- Select any beaten favorites *#a favorite that has a finish_position > 1*
The logic for determining favorites and beaten favorites is pretty straight forward (see above), but I’m having a hard time translating the logic into activerecord also is this an example were activerecord scopes could be utilized.
Here’s my attempt at favorite:
Starter.joins(:race).where(:finish_position => minimum(finish_position))
This isn’t working, but I still working at it.
I guess the ideal would be to have a favorite scope and a beaten scope.
2 Solutions collect form web for “How can I use activerecord's query interface and scopes to identify the favorite in a race”
For favorites, you can use this
favorites = Starter.group(:race_id).having('min(odds)')
For beaten favorites
beaten_favorites = favorites.where(['finish_position > ?', 1])
Some principles at first:
The “favorite” and “bean_favorites” only make sense when a race exists. So they are better to be instance methods instead of class methods.
Your race should know no more than one level of Starter’s methods, according Single Responsibility Principle
Now comes the code
class Race < ActiveRecord::Base def favorite starters.lowest_odds end def beaten_favorite starters.finished_lowest_odds end end class Starter < ActiveRecords::Base scope :by_odds, order('odds DESC') scope :finished, where('finished_position > 1') def lowest_odds by_odds.last end def finished_lowest_odds finished.lowest_odds end end
Now to solve the question