There's a very subtle issue I stumbled upon today if a union-ed scope is passed into ActiveRecord::Relation#merge. Any criteria from a union-built scope gets ignored when the relation gets merged into the scope chain.
I think this would probably be extremely hard to fix without monkey-patching pretty sensitive code in Relation::Merger, so the best advice I can see here would be to advise users to call #to_a on a union scope before passing it in to merge so that it continues to affect the query results.
A contrived example:
class Dog < ApplicationRecord
has_many :bones
end
class Bone < ApplicationRecord
belongs_to :dog
end
unioned_scope = Dog.where(id: [1, 2]).union(Dog.where(id: [4, 5]))
# This will return bones for Dog #3, which isn't part of the unioned scope!
Bone.joins(:dog).merge(unioned_scope)
Hi!
There's a very subtle issue I stumbled upon today if a
union
-ed scope is passed intoActiveRecord::Relation#merge
. Any criteria from aunion
-built scope gets ignored when the relation gets merged into the scope chain.https://github.com/rails/rails/blob/fe76a95b0d252a2d7c25e69498b720c96b243ea2/activerecord/lib/active_record/relation/spawn_methods.rb#L31-L39
https://github.com/rails/rails/blob/fe76a95b0d252a2d7c25e69498b720c96b243ea2/activerecord/lib/active_record/relation/merger.rb#L25-L46
I think this would probably be extremely hard to fix without monkey-patching pretty sensitive code in
Relation::Merger
, so the best advice I can see here would be to advise users to call#to_a
on a union scope before passing it in tomerge
so that it continues to affect the query results.A contrived example: