-
-
Notifications
You must be signed in to change notification settings - Fork 829
Description
Hello,
I feel like there is a problem on the way to create the SQL query for a not_eq
ransack query with a relation.
For a simple not_eq
ransack params we have a simple SQL query which is easy to read and works well.
=>User.ransack(g: { '0': { firstname_not_eq: 'foo' } }).result.to_sql
>SELECT "users".* FROM "users" WHERE "users"."firstname" != 'foo'
but if I want to find a not equal value in a relation of my user model it's starting to be complicated. It will generate a weird SQL query which is, honestly, difficult to read because of the triple negation NOT IN ... NOT ... !=
=> User.ransack(g: { '0': { comments_upvote_not_eq: '1.0' } }).result.to_sql
> SELECT "users".* FROM "users" WHERE "users"."id" NOT IN (SELECT "comments"."user_id" FROM "comments" WHERE "comments"."user_id" = "users"."id" AND NOT ("comments"."upvote" != '1.0'))
With my few knowledge I would have expected an easier query like the first one, but I guess it's a generic approach for letting the possibility to create more complex combination.
The problem is this query seems to be wrong in the result. Here is a comparison between using ransack and activerecord.
=> User.joins(:comments).where("comments.article_id = 1 AND comments.upvote != '1.0'").count
SELECT COUNT(*) FROM "users" INNER JOIN "comments" ON "comments"."user_id" = "users"."id" WHERE (comments.article_id = 1 AND comments.upvote != '1.0')
> 20
=> User.ransack(g: { '0': { comments_article_id_eq: 1, comments_upvote_not_eq: '1.0' } }).result.size
SELECT COUNT(*) FROM "users" LEFT OUTER JOIN "comments" ON "comments"."user_id" = "users"."id" WHERE ("comments"."article_id" = 1 AND "users"."id" NOT IN (SELECT "comments"."user_id" FROM "comments" WHERE "comments"."user_id" = "users"."id" AND NOT ("comments"."upvote" != '1.0')))
> 0
It's weird because the SQL query look correct but the triple negation doesn't make it easy to understand or to find the difference between the first query and the second one.
I created a demo where you can test it yourself. The test can seems odd because it would return 20 times the same user but the problem is here.
Thank you for reading and taking a look to it.
Rails version:
7.0.2
Ruby version:
3.1.2
Ransack version:
4.0.0