brianhempel / active_record_union

UNIONs in ActiveRecord! Adds proper union and union_all methods to ActiveRecord::Relation.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`union` ignored if used in a merge

geoffharcourt opened this issue · comments

Hi!

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.

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 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)