Reputation: 82
For my app:
Perhaps the location's fields should just be part of the image. But regardless, I'm trying to write this query in Rails:
SELECT image.caption, location.latitude, location.longitude
FROM image, location
WHERE location.image_id = image.id
AND image.user_id = 5
or alternatively, if it's easier:
SELECT image.*, location.*
FROM image, location
WHERE location.image_id = image.id
AND image.user_id = 5
How would I write this as an ActiveRecord query?
Upvotes: 0
Views: 125
Reputation: 35370
I think you want to read about Eager Loading Associations.
@images = Image.includes(:location).where("images.user_id = ?", 5)
This will find Image
instances where user_id = 5
. It then runs a 2nd query that will JOIN
and build the associated Location
instance (thats what the .includes(:location)
will do for you).
This more closely matches your alternative query, as it does select all columns from images
and location
tables.
You can build an Array based on this containing a hash with only the keys you're interested in through something like this.
@hash_object = @images.collect { |i| { caption: i.caption, latitude: i.location.latitude, longitude: i.location.longitude } }
If you want to build this with only a single query, you can use .joins(:location)
in combination with .includes(:location)
Image.joins(:location).includes(:location).where("images.user_id = ?", 5)
Important: This will omit Image
instances who have no assoicated Location
. You can modify the joins()
a bit to help with this, but the above will have this omission.
If you really want only specific columns to be selected, read up on Selecting Specific Columns though there are warnings for the use of this
If the select method is used, all the returning objects will be read only.
and
Be careful because this also means you’re initializing a model object with only the fields that you’ve selected.
In Rails master (not out in 3.2.11) you can pass multiple columns to .pluck()
but this appears to only be restricted to a single table (you wouldn't be able to get the locations
table's :latitude
and :longitude
when plucking from Image
). It's good to know about though.
Upvotes: 1