Skip to content

Commit af3e1a2

Browse files
committed
add default scopes to through unions
1 parent d68fb2b commit af3e1a2

File tree

2 files changed

+32
-12
lines changed

2 files changed

+32
-12
lines changed

lib/union_of.rb

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
@@ -297,29 +313,31 @@ def join_scope(table, foreign_table, foreign_klass, alias_tracker = nil)
297313
end
298314

299315
# Create base join constraints and add default constraints if available
300-
through_constraints = through_table[through_reflection.join_primary_key].eq(
316+
through_constraint = through_table[through_reflection.join_primary_key].eq(
301317
foreign_table[through_reflection.join_foreign_key],
302318
)
303319

304320
unless (where_clause = through_klass.default_scoped.where_clause).empty?
305-
through_constraints = where_clause.ast.and(through_constraints)
321+
through_constraint = where_clause.ast.and(through_constraint)
306322
end
307323

308324
klass_scope.joins!(
309325
Arel::Nodes::OuterJoin.new(
310326
through_table,
311-
Arel::Nodes::On.new(through_constraints),
327+
Arel::Nodes::On.new(through_constraint),
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+
foreign_constraint = foreign_constraints.reduce(&:or)
339+
340+
klass_scope.where!(foreign_constraint)
323341
end
324342

325343
unless scope_chain_items.empty?

spec/lib/union_of_spec.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@
398398
)
399399
WHERE
400400
"licenses"."id" = '#{license.id}'
401+
ORDER BY
402+
"users"."created_at" ASC
401403
SQL
402404
end
403405

0 commit comments

Comments
 (0)