File tree Expand file tree Collapse file tree 3 files changed +54
-1
lines changed
lib/active_record/relation Expand file tree Collapse file tree 3 files changed +54
-1
lines changed Original file line number Diff line number Diff line change 162
162
163
163
* Jason Nochlin*
164
164
165
+ * The fix ensures that the association is joined using the appropriate join type
166
+ (either inner join or left outer join) based on the existing joins in the scope.
167
+
168
+ This prevents unintentional overrides of existing join types and ensures consistency in the generated SQL queries.
169
+
170
+ Example:
171
+
172
+
173
+
174
+ ``` ruby
175
+ # `associated` will use `LEFT JOIN` instead of using `JOIN`
176
+ Post .left_joins(:author ).where.associated(:author )
177
+ ```
178
+
179
+ * Saleh Alhaddad *
180
+
165
181
* Fix an issue where ` ActiveRecord::Encryption` configurations are not ready before the loading
166
182
of Active Record models, when an application is eager loaded. As a result, encrypted attributes
167
183
could be misconfigured in some cases.
Original file line number Diff line number Diff line change @@ -72,10 +72,26 @@ def not(opts, *rest)
72
72
# # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
73
73
# # INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
74
74
# # WHERE "authors"."id" IS NOT NULL AND "comments"."id" IS NOT NULL
75
+ #
76
+ # You can define join type in the scope and +associated+ will not use `JOIN` by default.
77
+ #
78
+ # Post.left_joins(:author).where.associated(:author)
79
+ # # SELECT "posts".* FROM "posts"
80
+ # # LEFT OUTER JOIN "authors" "authors"."id" = "posts"."author_id"
81
+ # # WHERE "authors"."id" IS NOT NULL
82
+ #
83
+ # Post.left_joins(:comments).where.associated(:author)
84
+ # # SELECT "posts".* FROM "posts"
85
+ # # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
86
+ # # LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id"
87
+ # # WHERE "author"."id" IS NOT NULL
75
88
def associated ( *associations )
76
89
associations . each do |association |
77
90
reflection = scope_association_reflection ( association )
78
- @scope . joins! ( association )
91
+ unless @scope . joins_values . include? ( reflection . name ) || @scope . left_outer_joins_values . include? ( reflection . name )
92
+ @scope . joins! ( association )
93
+ end
94
+
79
95
if reflection . options [ :class_name ]
80
96
self . not ( association => { reflection . association_primary_key => nil } )
81
97
else
Original file line number Diff line number Diff line change @@ -92,6 +92,27 @@ def test_associated_with_enum_extended_late
92
92
assert_equal Author . find ( 2 ) , Author . order ( id : :desc ) . joins ( :reading_listing ) . where . associated ( :reading_listing ) . extending ( Author ::NamedExtension ) . first
93
93
end
94
94
95
+ def test_associated_with_add_joins_before
96
+ Comment . joins ( :children ) . where . associated ( :children ) . tap do |relation |
97
+ assert_includes relation , comments ( :greetings )
98
+ assert_not_includes relation , comments ( :more_greetings )
99
+ end
100
+ end
101
+
102
+ def test_associated_with_add_left_joins_before
103
+ Comment . left_joins ( :children ) . where . associated ( :children ) . tap do |relation |
104
+ assert_includes relation , comments ( :greetings )
105
+ assert_not_includes relation , comments ( :more_greetings )
106
+ end
107
+ end
108
+
109
+ def test_associated_with_add_left_outer_joins_before
110
+ Comment . left_outer_joins ( :children ) . where . associated ( :children ) . tap do |relation |
111
+ assert_includes relation , comments ( :greetings )
112
+ assert_not_includes relation , comments ( :more_greetings )
113
+ end
114
+ end
115
+
95
116
def test_missing_with_association
96
117
assert_predicate posts ( :authorless ) . author , :blank?
97
118
assert_equal [ posts ( :authorless ) ] , Post . where . missing ( :author ) . to_a
You can’t perform that action at this time.
0 commit comments