This blog is part of our Rails 5 series.

Rails 5 has added OR method to Active Relation for generating queries with OR clause.

>> Post . where ( id: 1 ). or ( Post . where ( title: 'Learn Rails' )) SELECT "posts" . * FROM "posts" WHERE ( "posts" . "id" = ? OR "posts" . "title" = ?) [[ "id" , 1 ], [ "title" , "Learn Rails" ]] => < ActiveRecord :: Relation [ #<Post id: 1, title: 'Rails'>]>

This returns ActiveRecord::Relation object, which is logical union of two relations.

Some Examples of OR usage

With group and having

>> posts = Post . group ( :user_id ) >> posts . having ( 'id > 3' ). or ( posts . having ( 'title like "Hi%"' )) SELECT "posts" . * FROM "posts" GROUP BY "posts" . "user_id" HAVING (( id > 2 ) OR ( title like "Rails%" )) => < ActiveRecord :: Relation [ #<Post id: 3, title: "Hi", user_id: 4>, #<Post id: 6, title: "Another new blog", user_id: 6>]>

With scope

class Post < ApplicationRecord scope :contains_blog_keyword , -> { where ( "title LIKE '%blog%'" ) } end >> Post . contains_blog_keyword . or ( Post . where ( 'id > 3' )) SELECT "posts" . * FROM "posts" WHERE (( title LIKE '%blog%' ) OR ( id > 3 )) => < ActiveRecord :: Relation [ #<Post id: 4, title: "A new blog", user_id: 6>, #<Post id: 5, title: "Rails blog", user_id: 4>, #<Post id: 6, title: "Another new blog", user_id: 6>]>

With combination of scopes

class Post < ApplicationRecord scope :contains_blog_keyword , -> { where ( "title LIKE '%blog%'" ) } scope :id_greater_than , -> ( id ) { where ( "id > ?" , id )} scope :containing_blog_keyword_with_id_greater_than , -> ( id ) { contains_blog_keyword . or ( id_greater_than ( id )) } end >> Post . containing_blog_keyword_with_id_greater_than ( 2 ) SELECT "posts" . * FROM "posts" WHERE (( title LIKE '%blog%' ) OR ( id > 2 )) ORDER BY "posts" . "id" DESC => < ActiveRecord :: Relation [ #<Post id: 3, title: "Hi", user_id: 6>, #<Post id: 4, title: "A new blog", user_id: 6>, #<Post id: 5, title: "Another new blog", user_id: 6>, < #Post id: 6, title: "Another new blog", user_id: 6>]>

Constraints for using OR method

The two relations must be structurally compatible, they must be scoping the same model, and they must differ only by WHERE or HAVING .

In order to use OR operator, neither relation should have a limit , offset , or distinct .

>> Post . where ( id: 1 ). limit ( 1 ). or ( Post . where ( :id => [ 2 , 3 ])) ArgumentError : Relation passed to #or must be structurally compatible. Incompatible values: [:limit]

When limit , offset or distinct is passed only with one relation, then it throws ArgumentError as shown above.

As of now, we can use limit , offset or distinct when passed with both the relations and with same the parameters.

>> Post . where ( id: 1 ). limit ( 2 ). or ( Post . where ( :id => [ 2 , 3 ]). limit ( 2 )) SELECT "posts" . * FROM "posts" WHERE ( "posts" . "id" = ? OR "posts" . "id" IN ( 2 , 3 )) LIMIT ? [[ "id" , 1 ], [ "LIMIT" , 2 ]] => < ActiveRecord :: Relation [ #<Post id: 1, title: 'Blog', user_id: 3, published: true>, #<Post id: 2, title: 'Rails 5 post', user_id: 4, published: true>]>