-
-
Notifications
You must be signed in to change notification settings - Fork 810
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Searching across multiple associations that reference the same model/table joining on the wrong association #374
Comments
Hi @jhdavids8, thanks for the report. Just merged in a fix by @dush for a merged join issue on the |
Unfortunately, it doesn't seem to have fixed the issue. I'm still seeing the same specs fail for the same reasons. |
I'm getting hit with this issue too when upgrading to Rails 4.1 class User < ActiveRecord::Base
has_many :comments
has_many :foo, through: :comments
end
class Comment < ActiveRecord::Base
belongs_to :user
has_many :foo
end
class Foo < ActiveRecord::Base
belongs_to :comment
end
User.first.foo.search(:comment_user_name_eq => "omg").result.to_sql This produces different code in 4.0 vs 4.1 Rails 4.1 SELECT "foos".* FROM "foos"
LEFT OUTER JOIN "comments" "comments_foos" ON "comments_foos"."id" = "foos"."comment_id"
LEFT OUTER JOIN "users" ON "users"."id" = "comments"."user_id"
INNER JOIN "comments" ON "foos"."comment_id" = "comments"."id"
WHERE "comments"."user_id" = ? AND "users"."name" = 'omg' Rails 4.0 SELECT "foos".* FROM "foos"
LEFT OUTER JOIN "comments" "comments_foos" ON "comments_foos"."id" = "foos"."comment_id"
LEFT OUTER JOIN "users" ON "users"."id" = "comments_foos"."user_id"
INNER JOIN "comments" ON "foos"."comment_id" = "comments"."id"
WHERE "comments"."user_id" = ? AND "users"."name" = 'omg' Note that the differences is in this line LEFT OUTER JOIN "users" ON "users"."id" = "comments"."user_id" This happens on Master and Rails 4.1. Here is a repo with the code I used to create the above: If you can point me in the right direction I can try to help, when I'm not working. |
It's likely to be in @huoxito wdyt? |
My initial guess is Ransack::Context#build_for_find_association. It's hard to tell for sure without further investigation though. It might as well as be something wrong in rails. Looking into it. I think we could also try to improve that same method to use more of activerecord public api. Chances are we'd have a more reliable implementation. @arjes @jhdavids8 any chance you guys could give us a spec that would fail on 4.1 but pass on 4.0? That should help a lot to fix the issue and ensure it doesn't happen again. |
@huoxito yes, my initial guess would be in that method. |
Hi @huoxito I'm looking into this now. Stay tuned! |
Well, this is a pretty poor effort at a spec that fails on 4.1 but not on 4.0, but here it is. I did as much digging as time allowed, but my lack of knowledge on the inner workings of ActiveRecord and Polyamorous prevented me from getting too far. The error definitely appears to be in Ransack::Context#build_for_find_association though. Everything appeared normal up to line 177, where the JoinDependency is built. That dependency appeared to have nothing that linked it to the aliased association (in my code, this was :target_person) over the non-aliased one (just :person). Sorry, but that's as far as I could get for now. If you guys don't beat me to a solution, I'll try to find some more time to dig deeper later in the week. Thanks! |
Thank you @jhdavids8! I'll take a look again and try out the spec as soon as I get some spare time, let you know if I find any solution |
It looks like the 4.1 conditional branch builds a new JoinDependency, but the "else" branch uses the assigned |
Any update on this issue? I have the exact same issue where ransack fails to find the renamed column and thus generates a postgres error. |
Thanks for the heads up. If there was an update I would try to make sure it was referenced here and visible. Anyone who is affected by this issue is most welcome to work on a fix. |
Issue also occured in rails 4.2 with ransack 1.5.1. Fix would be great! |
Same issue with rails 4.1.0 and ransack 1.6.2 |
Same issue with rails 4.1.8 and ransack 1.6.4, 4.1 branch, and current master branch |
@jhdavid8 thanks for the regression test, which is the first step toward a fix 👍 Everyone else: Thanks for the reports, but you need to provide a test or use someone's test like @jhdavids8's and show the test and its output, otherwise your report is not useful because not precisely reproducible and testable. You need to show a failing test. I merged @jhdavids8's spec into Ransack and can confirm that it passes in Rails 4-0-stable, but not in 4-1-stable, 4-2-stable and 5.0.0.alpha / master. Here is the output when the spec fails (the result is the same with 4-1-stable, 4-2-stable, 5.0.0.alpha, and using SQLite3): ∴ DB=PostgreSQL bundle exec rake spec
===================================================================================
Running specs against PostgreSQL, Active Record 5.0.0.alpha and Arel 7.0.0.alpha...
===================================================================================
...................................................................................
...................................................................................
....................................................................F..............
.....
Failures:
1) Ransack::Search#result evaluates conditions for multiple belongs_to associations
to the same table contextually
expected:
"SELECT \"recommendations\".* FROM \"recommendations\"
LEFT OUTER JOIN \"people\" ON \"people\".\"id\" = \"recommendations\".\"person_id\"
LEFT OUTER JOIN \"people\" \"target_people_recommendations\"
ON \"target_people_recommendations\".\"id\" = \"recommendations\".\"target_person_id\"
LEFT OUTER JOIN \"people\" \"parents_people\"
ON \"parents_people\".\"id\" = \"target_people_recommendations\".\"parent_id\"
WHERE ((\"people\".\"name\" = 'Ernie' AND \"parents_people\".\"name\" = 'Test'))"
got:
"SELECT \"recommendations\".* FROM \"recommendations\"
LEFT OUTER JOIN \"people\" ON \"people\".\"id\" = \"recommendations\".\"person_id\"
LEFT OUTER JOIN \"people\" \"target_people_recommendations\"
ON \"target_people_recommendations\".\"id\" = \"recommendations\".\"target_person_id\"
LEFT OUTER JOIN \"people\" \"parents_people\"
ON \"parents_people\".\"id\" = \"people\".\"parent_id\"
WHERE (\"people\".\"name\" = 'Ernie' AND \"parents_people\".\"name\" = 'Test')"
# ./spec/ransack/search_spec.rb:220:in `block (3 levels) in <module:Ransack>' |
Pushed the spec to Ransack master to help anyone who wants / needs to fix this issue:
|
- Add a Active Record conditional so there are only 2 lines to comment out if someone would like to work on #374. - Improve the SQL query readability.
There is also this: rails/rails#19427 (comment) |
Here's yet another gist related to this issue: https://gist.github.com/linkyndy/e84534e1cdc19dd8e4cc I've posted it just to raise awareness of this bug :) |
Looks like it's not properly referencing a table alias. You can see a diff from the two AST's here: |
FYI: I was able to work around the issue of @linkyndy by defining an extra association |
The main reason for these issues is the Rails 4.1 code transitioning from matching joins on JoinAssociations to JoinDependencys (which have their own AliasTracker that is not coalesced with other JoinDependency's AliasTrackers). I am not sure if this is a active design decision on the part of the Rails team, but for a patch on the Ransack side, we would need to build a singular (correctly aliased) JoinDependency (or monkeypatch the Rails code to support attaching JoinAssociations |
I worked around the issue by dynamically creating the necessary associations in a Rails initialiser (code here). It might be an idea to fix the issue by relying on a more stable Rails API? Any ideas on possible side effects of this patch are highly appreciated. |
Closed due to age |
Hi all!
Let's say I have a model such as:
Now, say my Ransack search filters looks like this (as JSON, as I'm using Ransack with a REST API. Hopefully, it's more readable):
When I was on Rails 4.0.2 and Ransack 1.2.1, this was the SQL output I received:
Notice how the group is joined here (4th line, last LEFT OUTER JOIN).
However, after upgrading to Rails 4.1.1 and the Ransack 4.1 branch, this is the SQL output, which is wrong, as notice now how the group is joined (it's joined on the first user association, not the target user association).
This is consistent across several specs I have failing at the moment. Any query on an association for the second user association will fail, as it joins on the former user association.
Hopefully this is enough to get you guys started, but if not, please let me know. I'm going to try and find some time to dig deeper myself. Thanks!
The text was updated successfully, but these errors were encountered: