ruby on rails - Combine two ActiveRecord::Relation objects

ID : 20287

viewed : 13

Tags : ruby-on-railsrails-activerecordarelruby-on-rails

Top 5 Answer for ruby on rails - Combine two ActiveRecord::Relation objects

vote vote


If you want to combine using AND (intersection), use merge:


If you want to combine using OR (union), use or:


Only in ActiveRecord 5+; for 4.2 install the where-or backport.

vote vote


Relation objects can be converted to arrays. This negates being able to use any ActiveRecord methods on them afterwards, but I didn't need to. I did this:

name_relation = first_name_relation + last_name_relation 

Ruby 1.9, rails 3.2

vote vote


merge actually doesn't work like OR. It's simply intersection (AND)

I struggled with this problem to combine to ActiveRecord::Relation objects into one and I didn't found any working solution for me.

Instead of searching for right method creating an union from these two sets, I focused on algebra of sets. You can do it in different way using De Morgan's law

ActiveRecord provides merge method (AND) and also you can use not method or none_of (NOT).

search.where.none_of(search.where.not(id: ids_to_exclude).merge(search.where.not("title ILIKE ?", "%#{query}%"))) 

You have here (A u B)' = A' ^ B'

UPDATE: The solution above is good for more complex cases. In your case smth like that will be enough:

User.where('first_name LIKE ? OR last_name LIKE ?', 'Tobias', 'Fünke') 
vote vote


I've been able to accomplish this, even in many odd situations, by using Rails' built-in Arel.

User.where(   User.arel_table[:first_name].eq('Tobias').or(     User.arel_table[:last_name].eq('Fünke')   ) ) 

This merges both ActiveRecord relations by using Arel's or.

Merge, as was suggested here, didn't work for me. It dropped the 2nd set of relation objects from the results.

vote vote


There is a gem called active_record_union that might be what you are looking for.

It's example usages is the following:

current_user.posts.union(Post.published) current_user.posts.union(Post.published).where(id: [6, 7]) current_user.posts.union("published_at < ?", user_1.posts.union(user_2.posts).union(Post.published) user_1.posts.union_all(user_2.posts) 

Top 3 video Explaining ruby on rails - Combine two ActiveRecord::Relation objects