9

How do you add two relations together? When I try the + operator it returns an array. But I need it to return a relation.

thanks, mike

Mike Glaz
  • 5,352
  • 8
  • 46
  • 73
  • Why can't you make scopes to get all you need? Is something complex or you just can't do in this case? If is something you can make at database level, don't let it come to the application level. – Paulo Henrique Feb 18 '14 at 17:12

3 Answers3

8

Try:

new_relation = relation.merge(another_relation)
xdazz
  • 158,678
  • 38
  • 247
  • 274
3

You can add two ActiveRecord::Relation with Arel Constraints

constraints_1 = Model.matching_one.arel.constraints
constraints_2 = Model.matching_two.arel.constraints

Model.where(constraints_1.and(constraints_2)).class => ActiveRecord::Relation

You can use or operator too

Model.where(constraints_1.or(constraints_2)).class => ActiveRecord::Relation

Real example

constraints_1 = User.where(id: 1..5).arel.constraints
constraints_2 = User.where('id != 2').arel.constraints

User.where(constraints_1.and(constraints_2))

You can watch excellent screen cast about that http://railscasts.com/episodes/355-hacking-with-arel

Joel AZEMAR
  • 2,506
  • 25
  • 31
2

If you are adding ActiveRecord::Relation objects to get an 'OR' result rather than 'AND' (you'd get 'AND' behavior by chaining), and you still need the result to be an ActiveRecord::Relation to play nice with some other code (meta_search, for example)....

def matching_one_or_two
  temp = Model.matching_one + Model.matching_two
  Model.where('id in (?)',temp.map(&:id))
end

Certainly not the world's greatest performance, but it results in an ActiveRecord::Relation object pointing at the 'OR' results.

You can also just put the "OR" directly into the sql, rather than asking Rails to generate it for you, to give your database application a chance to perform better. One example:

Model.where("table_name.col = 'one' OR table_name.col = 'two'")

That will also return an ActiveRecord::Relation object.

Anatortoise House
  • 4,941
  • 1
  • 22
  • 18