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

92

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

first_name_relation.merge(last_name_relation) 

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

first_name_relation.or(last_name_relation) 

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

vote vote

85

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

77

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

60

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

55

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 < ?", Time.now) 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

Related QUESTION?