Reputation: 402
I want to retrieve a list of all Downloads as a result of a particular users content. For example, If I have 2 uploads, I want to filter the contents of the Download table to show only those downloads related to my Uploads.
Users {
user_id: integer
}
Upload {
upload_id: integer
user_id: integer (FK)
}
Download {
download_id: integer
upload_id: integer (FK)
}
The downloads table is a log of every public user that has downloaded a file ("upload") on my blog. As you can see, an Upload is linked to a user (user can have many uploads) and a download is linked to an upload (one upload can be downloaded many times).
This is the solution I am using so far (it's really messy and probably very inefficient):
@user = User.find_by_id(3)
# grab a list of the User 3's upload ids, e.g. [3, 6, 2, 34, 45]
@upload_ids = @user.uploads.map { |u| u.upload_id }
# now find all Downloads that have these id numbers in their upload_id
@downloads = Download.where(:upload_id => @upload_ids)
I'm sure there is a way to achieve this with table joins. UPDATE: All associations are explicitly configured.
Upvotes: 0
Views: 36
Reputation: 176552
Assuming all the associations are explicitly configured, you can use something like:
Download.joins(:upload).where("uploads.user_id = ?", 3)
You can already improve your query by making some assumptions:
pluck
instead of mapping over the idsHere's an example of using 2 optimized queries with no JOIN:
@downloads = Download.where(upload_id: Upload.where(user_id: 3).ids)
Upvotes: 1