71

So in Rails 4 the long desired feature to use not queries has been added.

Article.where.not(title: 'Rails 3')

Has similar support been added for or queries, or are they planning to make it. I couldn't find anything by browsing through the release notes.

Obviously I tried

Article.where(title: 'Rails 3').or(title: 'Rails 4')

But that does not work.

Arjan
  • 6,264
  • 2
  • 26
  • 42
  • 1
    if you like the syntax `Article.where(title: 'Rails 3').or(title: 'Rails 4')`, you could use [rails_or](https://github.com/khiav223577/rails_or). – khiav reoy Jan 02 '17 at 05:20

6 Answers6

99
Article.where(title: ['Rails 3', 'Rails 4'])

is how you'd do that in Active Record.

It's not possible to replicate any arbitrary SQL query using "Rails-y" syntax. But you can always just pass in literal sql.

So you could also do:

Article.where("articles.title = 'Rails 3' OR articles.title = 'Rails 4'")
gregates
  • 6,607
  • 1
  • 31
  • 31
  • 1
    True in this case. But this won't work for more complex conditions. – Arjan Jun 19 '13 at 13:45
  • 1
    That's what I was afraid of. I know you can do it with arbitrary sql. But that is exactly what I was trying to avoid. I hoped, that since they added `not` queries, they would support `or` queries as well. – Arjan Jun 19 '13 at 13:54
  • Obviously I can't speak to the future plans of the rails core team! You might try opening an issue on the github repo. – gregates Jun 19 '13 at 13:57
  • I might, or I will go ahead and try @PriteshJ's suggestion. That being said, your answer is correct and I will accept it now. – Arjan Jun 19 '13 at 13:59
  • I guess the any_of gem is the only solution here? – Donato Jun 03 '15 at 21:13
  • In my case (rails 4.0.13), it dropped the records found from the first 'where' clause, and returned only those found in the 2nd clause. Note I do have a 'join', and the clauses work fine separately. Guess I have to write a class method to sum the IDs from each search, and then re-query with where(:id => id_set) - unless/until there is a way to sum AR sets. – JosephK Jan 31 '16 at 09:16
  • 1
    You **really** should use `Article.where( "articles.title = ? OR articles.title = ?", "Rails 3", "Rails 4" )` to avoid SQL injection. – Joshua Pinter Nov 17 '19 at 03:46
  • 2
    You aren't vulnerable to SQL injection if your query doesn't contain user input. `Article.where("articles.title = '#{some_var}'")` *might* be vulnerable to SQL injection attacks, but `Article.where("articles.title = 'Rails 3' OR articles.title = 'Rails 4'")` is not. – gregates Nov 18 '19 at 22:27
  • Yes, but providing an example where they come from a user will make the answer better. – x-yuri Jan 26 '22 at 19:52
39

This now works in Rails 5:

Article.where(title: 'Rails 3').or(Article.where(title: 'Rails 4'))

Code example in Rails's source.

Fellow Stranger
  • 32,129
  • 35
  • 168
  • 232
  • 4
    Even with this change in Rails 5, I would stick with @gregates answer and use this syntax `Article.where(title: ['Rails 3', 'Rails 4'])`. It's less verbose and matches the common usage of `Article.where(id: [1, 2, 3, 4])` – BigRon Sep 19 '16 at 21:36
  • 9
    This solution has the advantage that you can use different columns in the two queries. – Eric Duminil Nov 10 '16 at 12:51
  • Another advantage is it works well with overriding methods that return queries `super.or(Article.where(title: 'Rails 4'))` – Subtletree Nov 05 '17 at 23:06
10

The most common alternative is already answer by @gregates

Recently there has been pull request in rails source

Add #any_of query method to active_record Which adds or functionality to activerecord

the contributor has already created a gem incase its not accepted

its rails 3.2 and 4 compatible

https://github.com/oelmekki/activerecord_any_of

I havent tried it yet but soon wish to use it looks good to me.

Pritesh Jain
  • 9,106
  • 4
  • 37
  • 51
5

I know that this is an old thread, but anyone else looking for a solution to this problem might find this code helpful:

Article.where(title: ["Rails 3", "Rails 4"])

Maybe that will help you get someone going in the right direction without having to risk sql injection.

KaptajnKold
  • 10,638
  • 10
  • 41
  • 56
Rob Richey
  • 75
  • 1
  • 1
4

It seems that the rails master branch is now supporting OR queries. https://github.com/rails/rails/pull/16052

I assume it will be in the framework with the next major release.

Arjan
  • 6,264
  • 2
  • 26
  • 42
  • Yup, dhh said we'll have it in Rails 5: https://github.com/rails/rails/pull/16052#issuecomment-72718557 – amoebe Feb 05 '15 at 21:45
2

Rails 5 will support it but you can use this backport for Rails 4.2 : https://github.com/Eric-Guo/where-or

Nicolas Maloeuvre
  • 3,069
  • 24
  • 42