简体   繁体   中英

Using calculations with has_many, :through ActiveRecord relations?

I'm trying to figure out how to best go about this… I have Competitions, which take place every day, with Contestants taking part, and they get each get a score in every competition. I want to be able to retrieve the total score for each Contestant in the Competitions that have taken place over a certain period of time, and get a "virtual" Competition model (ie one single row ) still usable by Rails.


My code/data is structured like this:

Competition:
has_many :contestant_scores
has_many :contestants, through: :contestant_scores
Columns: id, date

Contestant:
has_many :contestant_scores
Columns: id, name

ContestantScore:
belongs_to :competition
belongs_to :contestant
Columns: competition_id, contestant_id, score


Given the following data:

(competitions)
id | date
---------------
0  | 2013-01-01
1  | 2013-01-02
2  | 2013-01-03

(contestants)
id | name
--------------
0  | Jake
1  | Finn
2  | Bubblegum

(contestant_scores)
competition_id | contestant_id | score
--------------------------------------
0              | 0             | 1
0              | 1             | 2
0              | 2             | 3
1              | 0             | 1
1              | 1             | 2
1              | 2             | 3
2              | 0             | 1
2              | 1             | 2
2              | 2             | 3

How would I go about retrieving all Competitions between 2013-01-01 and 2013-01-03, and get the total score for each contestant (sorted by highest score first)? Basically, I want:

  • a single Competition result with a nil id and date (since it's "virtual")
  • to be able to do virtual_competition.scores.first.score and get 9
  • to be able to do virtual_competition.scores.first.contestant.name and get "Bubblegum"

I hope this makes sense at all, and hope you can point me in the right direction. I'm not averse to using more "pure" SQL if need be, the important part is that I will be able to utilize ActiveRecord's object mapping with the result.

I'm using Postgres for the database if that makes any difference.

start_date = Date.new("2013-01-01")
end_date = Date.new("2013-01-03")
Competition.include(:contestant_scores => :contestant).where(:date => start_date..end_date).group("contestants.id").order("contestant_scores.score")

I think you need something like that

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM