Reputation: 1203
Rails 5.1.2
These are the two models in question.
class Person < ApplicationRecord
has_many :awards
end
class Award < Application Record
belongs_to :person
end
The Award
model has a column called rank
which can be 1
, 2
, or 3
, and a column called category
(also integers, but let's just use letters for now).
I'm trying to rank People
based on their awards
of a certain rank. Many people can have the same amount of a rank. For example, 40 people might have 30 rank 1 awards of category X.
For example:
A
People
Granted the Award
with Rank
1
8 TimesPeople
Granted the Award
with Rank
2
30 TimesPeople
Granted the Award
with Rank
3
60 TimesI want to build a query that returns a collection of People
.
Logically, this is what my query should do (in pseudo code):
Get all `people` who have the maximum `count` of awards where `awards.category` is `A` and `awards.rank` is `1`.
...and repeat this for rank 2
and rank 3
.
A counter_cache would not work because of the implication of categories (unless I create a counter_cache for each category, but that feels far redundant and not flexible).
As usual, an idea that sounded simple turned out to be far more complex than I thought, and I have no idea how to pull this off.
Upvotes: 1
Views: 77
Reputation: 6603
awards_having_max_count_of_persons_for_each_category_and_rank = Award.group(:category, :rank).order('count(awards.person_id)')
# you can do something like this if you'd like to key-value pairs:
hash = {}
awards_having_max_count_of_persons_for_each_category_and_rank.each do |award|
hash[{category: award.category, rank: award.rank}] = award.person_id
end
puts hash
# => {
# {category: 1, rank: 1} => 1,
# {category: 1, rank: 2} => 3,
# {category: 1, rank: 3} => 2,
# {category: 2, rank: 1} => 9,
# ...
# }
# where 1, 3, 2, and 9 are person_ids
Upvotes: 1