Use include with references to build relations instead of left_join #593
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hello dear community,
Preambule
ActiveRecord handles multiple
.joins
calls carefully. For example,User.joins(:profile).joins(:profile)
generates only oneINNER JOIN
statement.ActiveRecord::QueryMethods#references
generates LEFT OUTER JOIN, but combination of.joins
and.references
with the same relation name produces correct SQL query with single INNER JOIN.Some people often write controllers like
and if we always use the same join style, the SQL builder will handle it and generate single
INNER JOIN profiles ON ...
statement. It works as "some people" expect.Everything goes wrong when we use mix of
left_joins
andjoins
methods. The builder builds "LEFT OUTER JOIN profiles" with "INNER JOIN profiles" in the same time, in the same query. And databases (PG, for example) raise exception when meet several joins on the same table with (or without) the same aliases.Problem
CanCanCan 2.0 used include with references to build relations for accessible_by method. CanCanCan 3.0 replaced it with
left_join
. As the result, a lot of legacy smelly code is broken.For example, this code will generate invalid "LEFT OUTER JOIN profiles ON ... LEFT JOIN profiles ON` query:
Fix
I returned old behavior. I cannot see valuable advantages to use left_join instead of the old
includes.references
chain. Please correct me if I'm mistaken.Thank you.