Reputation: 415
I have two models. Category and Photo. There are many photos for each category.
I want to order a category object array in such a way that it is ordered by an attribute in the Photo model. Specifically how many times a photo is downloaded.
I am trying to initiate the instance variable with something like
@category = Category.active.order('photos.qty_download DESC)
I would then use that instance variable to list the categories and how many photos have been downloaded for each category
Chicago 45
San Fran 32
Boston 23
etc
What expression will work in Rails?
Thanks
Upvotes: 0
Views: 88
Reputation: 381
Category.includes(:photos).order(qty_download: :desc).reference(:photos)
Upvotes: 0
Reputation: 1985
Let's assume that your models look something like this:
class Category < ActiveRecord::Base
has_many :photos
end
class Photo < ActiveRecord::Base
belongs_to :category
end
Let's also assume:
qty_download
field as you describe in your
questionname
fieldqty_download
for all of the photos in each
categoryWith those assumptions, you should be able to write
Category.
joins(:photos).
group("categories.id, categories.name").
select("categories.id, categories.name, sum(photos.qty_download) as total_downloads").
order("total_downloads desc")
Note that what will be returned will be "partial" category objects that contain only id
, name
, and total_downloads
. If you want additional category fields, add them to both the group
and the select
clauses.
Update
Newer versions of Postgres allow a simplification of the query:
Category.
joins(:photos).
group("categories.id").
select("categories.*, sum(photos.qty_download) as total_downloads").
order("total_downloads desc")
Note that in recent versions of Postgres, you can simply group by a unique id -- you no longer must group by all attributes that you which to include in your select. So you can now include all the attributes of categories as categories.*
. I'll leave the original in place as it is (marginally) more efficient and backwards-compatible with older versions of Postgres.
Upvotes: 2