I have two tables, posts and images. Here is the relevant section from schema.rb:
create_table "posts", force: true do |t|
t.string "name"
t.string "body"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "images", force: true do |t|
t.integer "post_id"
t.string "service_name"
t.string "service_url"
t.datetime "created_at"
t.datetime "updated_at"
end
I want to find all the posts and join it with the images table, with a where clause on the images. I still want all of the posts to return, even if they don't have images that match the where clause.
I still expect this query to return all the posts, even if there are no images with a service name of "acme":
Post.includes(:images).where("images.service_name" => "acme")
According to the rails guide on querying,
If, in the case of this includes query, there were no comments for any posts, all the posts would still be loaded. By using joins (an INNER JOIN), the join conditions must match, otherwise no records will be returned.
but that's not the behavior I'm seeing. In the case of no images, I'm getting no results pack from my query.
I appreciate any ideas.
If you add a WHERE
condition on columns of the right table after a LEFT JOIN
, you force it to act like an INNER JOIN
.
Pull the expression up into the condition to the LEFT JOIN
.
According to the manual page you quoted yourself:
the recommended way is to use joins instead.
And:
This would generate a query which contains a LEFT OUTER JOIN whereas the joins method would generate one using the INNER JOIN function instead.
You may have misread that sentence.
This should do what you want:
Post.joins('LEFT OUTER JOIN images ON images.post_id = posts.id
AND images.service_name = $$acme$$')
I am no Ruby expert, but deriving this from the manual here.
Not sure how to escape single quotes, so I switched to dollar-quoting instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With