Monday 3 September 2018

Enableecord Left Outer Join does not work with NOT

This query works:

person.posts.includes(:categories).
references(:categories).where(categories: { id: 20 })

But with the NOT condition:
person.posts.includes(:categories).
references(:categories).where.not(categories: { id: 20 })

The second query completes with no error - but no filtering is done on the results - so it returns all the posts.
The MySQL:
SELECT COUNT(DISTINCT `posts`.`id`) FROM `posts`
LEFT OUTER JOIN `category_manifests` ON `category_manifests`.`post_id` = `posts`.`id`
LEFT OUTER JOIN `categories` ON `categories`.`id` = `category_manifests`.`category_id`
WHERE `posts`.`person_id` = 14 AND (`categories`.`id` != 20)

I have not found anything in the Activerecord documentation to suggest this is not possible - am I missing something basic here?

Agreed with Max. I'd structure this condition like this:
.where("NOT EXISTS (
  SELECT * FROM category_manifests
  WHERE post_id = posts.id AND category_id = ?)",
    excluded_category.id)

instead, just because that way you can't get as tangled up in the join table mathematics.

0 comments:

Post a Comment