---
title: "Rails 5 adds OR support in Active Record"
description:
  "We will now be able to perform OR operation in Active Record without having
  to write custom SQL."
canonical_url: "https://www.bigbinary.com/blog/rails-5-adds-or-support-in-active-record"
markdown_url: "https://www.bigbinary.com/blog/rails-5-adds-or-support-in-active-record.md"
---

# Rails 5 adds OR support in Active Record

We will now be able to perform OR operation in Active Record without having to
write custom SQL.

- Author: Abhishek Jain
- Published: May 30, 2016
- Categories: Rails 5, Rails

Rails 5
[has added OR method](https://github.com/rails/rails/commit/b0b37942d729b6bdcd2e3178eda7fa1de203b3d0)
to Active Relation for generating queries with OR clause.

```ruby

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

```ruby

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

```ruby

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

```ruby

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`.

```ruby

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

```ruby

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

```

There is an [issue](https://github.com/rails/rails/issues/24055) open in which
discussions are ongoing regarding completely stopping usage of `limit`, `offset`
or `distinct` when using with `or`.

## Links

- [Human page](https://www.bigbinary.com/blog/rails-5-adds-or-support-in-active-record)
