ActiveRecord OR query

Ruby on-RailsRuby on-Rails-3Rails Activerecord

Ruby on-Rails Problem Overview


How do you do an OR query in Rails 3 ActiveRecord. All the examples I find just have AND queries.

> Edit: OR method is available since Rails 5. See ActiveRecord::QueryMethods

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

If you want to use an OR operator on one column's value, you can pass an array to .where and ActiveRecord will use IN(value,other_value):

Model.where(:column => ["value", "other_value"]

outputs:

SELECT `table_name`.* FROM `table_name` WHERE `table_name`.`column` IN ('value', 'other_value')

This should achieve the equivalent of an OR on a single column

Solution 2 - Ruby on-Rails

in Rails 3, it should be

Model.where("column = ? or other_column = ?", value, other_value)

This also includes raw sql but I dont think there is a way in ActiveRecord to do OR operation. Your question is not a noob question.

Solution 3 - Ruby on-Rails

Use ARel

t = Post.arel_table

results = Post.where(
  t[:author].eq("Someone").
  or(t[:title].matches("%something%"))
)

The resulting SQL:

ree-1.8.7-2010.02 > puts Post.where(t[:author].eq("Someone").or(t[:title].matches("%something%"))).to_sql
SELECT     "posts".* FROM       "posts"  WHERE     (("posts"."author" = 'Someone' OR "posts"."title" LIKE '%something%'))

Solution 4 - Ruby on-Rails

An updated version of Rails/ActiveRecord may support this syntax natively. It would look similar to:

Foo.where(foo: 'bar').or.where(bar: 'bar')

As noted in this pull request https://github.com/rails/rails/pull/9052

For now, simply sticking with the following works great:

Foo.where('foo= ? OR bar= ?', 'bar', 'bar')

Update: According to https://github.com/rails/rails/pull/16052 the or feature will be available in Rails 5

Update: Feature has been merged to Rails 5 branch

Solution 5 - Ruby on-Rails

Rails has recently added this into ActiveRecord. It looks to be released in Rails 5. Committed to master already:

https://github.com/rails/rails/commit/9e42cf019f2417473e7dcbfcb885709fa2709f89

Post.where(column: 'something').or(Post.where(other: 'else'))

# => SELECT * FROM posts WHERE (column = 'something') OR (other = 'else)

Solution 6 - Ruby on-Rails

Rails 5 comes with an or method. (link to documentation)

This method accepts an ActiveRecord::Relation object. eg:

User.where(first_name: 'James').or(User.where(last_name: 'Scott'))

Solution 7 - Ruby on-Rails

If you want to use arrays as arguments, the following code works in Rails 4:

query = Order.where(uuid: uuids, id: ids)
Order.where(query.where_values.map(&:to_sql).join(" OR "))
#=> Order Load (0.7ms)  SELECT "orders".* FROM "orders" WHERE ("orders"."uuid" IN ('5459eed8350e1b472bfee48375034103', '21313213jkads', '43ujrefdk2384us') OR "orders"."id" IN (2, 3, 4))

More information: OR queries with arrays as arguments in Rails 4.

Solution 8 - Ruby on-Rails

The MetaWhere plugin is completely amazing.

Easily mix OR's and AND's, join conditions on any association, and even specify OUTER JOIN's!

Post.where({sharing_level: Post::Sharing[:everyone]} | ({sharing_level: Post::Sharing[:friends]} & {user: {followers: current_user} }).joins(:user.outer => :followers.outer}

Solution 9 - Ruby on-Rails

Just add an OR in the conditions

Model.find(:all, :conditions => ["column = ? OR other_column = ?",value, other_value])

Solution 10 - Ruby on-Rails

You could do it like:

Person.where("name = ? OR age = ?", 'Pearl', 24)

or more elegant, install rails_or gem and do it like:

Person.where(:name => 'Pearl').or(:age => 24)

Solution 11 - Ruby on-Rails

I just extracted this plugin from client work that lets you combine scopes with .or., ex. Post.published.or.authored_by(current_user). Squeel (newer implementation of MetaSearch) is also great, but doesn't let you OR scopes, so query logic can get a bit redundant.

Solution 12 - Ruby on-Rails

With rails + arel, a more clear way:

# Table name: messages
#
# sender_id:    integer
# recipient_id: integer
# content:      text

class Message < ActiveRecord::Base
  scope :by_participant, ->(user_id) do
    left  = arel_table[:sender_id].eq(user_id)
    right = arel_table[:recipient_id].eq(user_id)

    where(Arel::Nodes::Or.new(left, right))
  end
end

Produces:

$ Message.by_participant(User.first.id).to_sql 
=> SELECT `messages`.* 
     FROM `messages` 
    WHERE `messages`.`sender_id` = 1 
       OR `messages`.`recipient_id` = 1

Solution 13 - Ruby on-Rails

Book.where.any_of(Book.where(:author => 'Poe'), Book.where(:author => 'Hemingway')

Solution 14 - Ruby on-Rails

I'd like to add this is a solution to search multiple attributes of an ActiveRecord. Since

.where(A: param[:A], B: param[:B])

will search for A and B.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionpho3nixf1reView Question on Stackoverflow
Solution 1 - Ruby on-RailsdeadkarmaView Answer on Stackoverflow
Solution 2 - Ruby on-RailsrubyprinceView Answer on Stackoverflow
Solution 3 - Ruby on-RailsDan McNevinView Answer on Stackoverflow
Solution 4 - Ruby on-RailsChristian FazziniView Answer on Stackoverflow
Solution 5 - Ruby on-RailsGreg OlsenView Answer on Stackoverflow
Solution 6 - Ruby on-RailsSanthoshView Answer on Stackoverflow
Solution 7 - Ruby on-RailsRafał CieślakView Answer on Stackoverflow
Solution 8 - Ruby on-RailsDukeView Answer on Stackoverflow
Solution 9 - Ruby on-RailsToby HedeView Answer on Stackoverflow
Solution 10 - Ruby on-Railskhiav reoyView Answer on Stackoverflow
Solution 11 - Ruby on-RailsWoahdaeView Answer on Stackoverflow
Solution 12 - Ruby on-RailsitsnikolayView Answer on Stackoverflow
Solution 13 - Ruby on-RailsMatthew RigdonView Answer on Stackoverflow
Solution 14 - Ruby on-RailsTomás GaeteView Answer on Stackoverflow