@@ -218,7 +218,11 @@ def next_chain_scope(scope, reflection, next_reflection)
218218 table = klass . arel_table
219219 foreign_klass = next_reflection . klass
220220 foreign_table = foreign_klass . arel_table
221- constraints = [ ]
221+
222+ # This holds our union's constraints. For example, if we're unioning across 3
223+ # tables, then this will hold constraints for all 3 of those tables, so that
224+ # the join on our target table mirrors the union of all 3 associations.
225+ foreign_constraints = [ ]
222226
223227 reflection . union_sources . each do |union_source |
224228 union_reflection = foreign_klass . reflect_on_association ( union_source )
@@ -231,21 +235,33 @@ def next_chain_scope(scope, reflection, next_reflection)
231235 through_reflection . name ,
232236 )
233237
234- constraints << foreign_table [ through_reflection . join_foreign_key ] . eq ( through_table [ through_reflection . join_primary_key ] )
238+ foreign_constraints << foreign_table [ through_reflection . join_foreign_key ] . eq ( through_table [ through_reflection . join_primary_key ] )
235239 else
236- constraints << foreign_table [ union_reflection . join_foreign_key ] . eq ( table [ union_reflection . join_primary_key ] )
240+ foreign_constraints << foreign_table [ union_reflection . join_foreign_key ] . eq ( table [ union_reflection . join_primary_key ] )
237241 end
238242 end
239243
244+ # Flatten union constraints and add any default constraints
245+ foreign_constraint = unless ( where_clause = foreign_klass . default_scoped . where_clause ) . empty?
246+ where_clause . ast . and ( foreign_constraints . reduce ( &:or ) )
247+ else
248+ foreign_constraints . reduce ( &:or )
249+ end
250+
240251 scope . joins! (
241252 Arel ::Nodes ::InnerJoin . new (
242253 foreign_table ,
243254 Arel ::Nodes ::On . new (
244- constraints . reduce ( & :or ) ,
255+ foreign_constraint ,
245256 ) ,
246257 ) ,
247258 )
248259
260+ # FIXME(ezekg) Why is this needed? Should be handled automatically...
261+ scope . merge! (
262+ scope . default_scoped ,
263+ )
264+
249265 scope
250266 end
251267
@@ -278,7 +294,7 @@ def join_scope(table, foreign_table, foreign_klass, alias_tracker = nil)
278294 # This holds our union's constraints. For example, if we're unioning across 3
279295 # tables, then this will hold constraints for all 3 of those tables, so that
280296 # the join on our target table mirrors the union of all 3 associations.
281- constraints = [ ]
297+ foreign_constraints = [ ]
282298
283299 union_sources . each do |union_source |
284300 union_reflection = foreign_klass . reflect_on_association ( union_source )
@@ -312,14 +328,14 @@ def join_scope(table, foreign_table, foreign_klass, alias_tracker = nil)
312328 ) ,
313329 )
314330
315- constraints << table [ source_reflection . join_primary_key ] . eq ( through_table [ source_reflection . join_foreign_key ] )
331+ foreign_constraints << table [ source_reflection . join_primary_key ] . eq ( through_table [ source_reflection . join_foreign_key ] )
316332 else
317- constraints << table [ union_reflection . join_primary_key ] . eq ( foreign_table [ union_reflection . join_foreign_key ] )
333+ foreign_constraints << table [ union_reflection . join_primary_key ] . eq ( foreign_table [ union_reflection . join_foreign_key ] )
318334 end
319335 end
320336
321- unless constraints . empty?
322- klass_scope . where! ( constraints . reduce ( &:or ) )
337+ unless foreign_constraints . empty?
338+ klass_scope . where! ( foreign_constraints . reduce ( &:or ) )
323339 end
324340
325341 unless scope_chain_items . empty?
0 commit comments