Rails: How to chain scope queries with OR instead of AND?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I'm using Rails3, ActiveRecord
Just wondering how can I chain the scopes with OR statements rather than AND.
e.g.
Person.where(:name => "John").where(:lastname => "Smith")
That normally returns name = 'John' AND lastname = 'Smith', but I'd like:
name = 'John' OR lastname = 'Smith'
ruby-on-rails activerecord ruby-on-rails-3
add a comment |
I'm using Rails3, ActiveRecord
Just wondering how can I chain the scopes with OR statements rather than AND.
e.g.
Person.where(:name => "John").where(:lastname => "Smith")
That normally returns name = 'John' AND lastname = 'Smith', but I'd like:
name = 'John' OR lastname = 'Smith'
ruby-on-rails activerecord ruby-on-rails-3
add a comment |
I'm using Rails3, ActiveRecord
Just wondering how can I chain the scopes with OR statements rather than AND.
e.g.
Person.where(:name => "John").where(:lastname => "Smith")
That normally returns name = 'John' AND lastname = 'Smith', but I'd like:
name = 'John' OR lastname = 'Smith'
ruby-on-rails activerecord ruby-on-rails-3
I'm using Rails3, ActiveRecord
Just wondering how can I chain the scopes with OR statements rather than AND.
e.g.
Person.where(:name => "John").where(:lastname => "Smith")
That normally returns name = 'John' AND lastname = 'Smith', but I'd like:
name = 'John' OR lastname = 'Smith'
ruby-on-rails activerecord ruby-on-rails-3
ruby-on-rails activerecord ruby-on-rails-3
edited Sep 10 '10 at 11:47
Shadwell
29.3k148089
29.3k148089
asked Sep 10 '10 at 11:41
user410715user410715
636264
636264
add a comment |
add a comment |
19 Answers
19
active
oldest
votes
You would do
Person.where('name=? OR lastname=?', 'John', 'Smith')
Right now, there isn't any other OR support by the new AR3 syntax (that is without using some 3rd party gem).
21
and just for safety's sake, it's worth expressing this as Person.where("name = ? OR lastname = ?", 'John', 'Smith')
– CambridgeMike
Nov 9 '11 at 3:55
6
This is still applicable in Rails 4? Nothing better came up in Rails 4?
– Donato
Apr 4 '15 at 21:18
11
No change in Rails 4, but Rails 5 will have.or
built in.
– lime
Jun 11 '15 at 6:53
3
this are not scopes, are just 2 where clauses, or a very specific scope case. What if I would like to chain more complex scopes, with joins for instance.
– miguelfg
Oct 22 '15 at 11:47
2
With Rails 5 you can also do something like, Person.where("name = 'John'").or(Person.where("lastname = 'Smith'"))
– shyam
Sep 28 '17 at 7:19
add a comment |
Use ARel
t = Person.arel_table
results = Person.where(
t[:name].eq("John").
or(t[:lastname].eq("Smith"))
)
1
Can anybody comment on whether this type of query breaks in Postgres?
– Olivier Lacan
Oct 28 '11 at 17:20
2
I'm using Postgres and this seemed to work fine.
– MrTheWalrus
Dec 7 '11 at 16:45
ARel is supposed to be DB-agnostic.
– Simon Perepelitsa
Jul 27 '12 at 16:17
While this looks like a good idea, ARel is not a public API and using this may break your app in unexpected ways, so I'd advise against it unless you pay close attention to the evolution of the ARel API.
– Olivier Lacan
Aug 28 '14 at 3:45
7
@OlivierLacan Arel is a public API, or more precisely, it exposes one. Active Record just provides convenience methods that use it under the hood, It's completely valid to use it on it's own. It follows semantic versioning, so unless you are changing major versions (3.x.x => 4.x.x), there is no need to worry about breaking changes.
– Gray
Sep 30 '14 at 13:46
add a comment |
According to this pull request, Rails 5 now supports the following syntax for chaining queries:
Post.where(id: 1).or(Post.where(id: 2))
There's also a backport of the functionality into Rails 4.2 via this gem.
add a comment |
Update for Rails4
requires no 3rd party gems
a = Person.where(name: "John") # or any scope
b = Person.where(lastname: "Smith") # or any scope
Person.where([a, b].map{|s| s.arel.constraints.reduce(:and) }.reduce(:or))
.tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
Old answer
requires no 3rd party gems
Person.where(
Person.where(:name => "John").where(:lastname => "Smith")
.where_values.reduce(:or)
)
5
this is really the only pure answer to the OP's question in terms of resources and method. the other answers either (a) require 3rd party apis or (b) require interpolatingor
or other operators within a text block, neither of which is reflected in OP's code.
– allenwlee
Feb 12 '15 at 21:24
6
here's a decent article explaining it coderwall.com/p/dgv7ag/…
– allenwlee
Feb 12 '15 at 21:37
4
Used...where_values.join(' OR ')
in my case
– Sash
May 31 '15 at 17:56
5
How does this work in scopes?
– baash05
Jul 20 '15 at 2:20
2
You can omit the.tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
part if your scopes don't have any variables that need binding.
– fatuhoku
May 10 '16 at 12:44
add a comment |
Just posting the Array syntax for same column OR queries to help peeps out.
Person.where(name: ["John", "Steve"])
2
The question check John against name and Smith against lastname
– steven_noble
Aug 8 '15 at 1:21
11
@steven_noble - that's why I bolded "same column" with the or query. I can delete the comment altogether, but thought it would be helpful for people perusing "or" query SO questions.
– daino3
Aug 10 '15 at 19:19
add a comment |
In case anyone is looking for an updated answer to this one, it looks like there is an existing pull request to get this into Rails: https://github.com/rails/rails/pull/9052.
Thanks to @j-mcnally's monkey patch for ActiveRecord (https://gist.github.com/j-mcnally/250eaaceef234dd8971b) you can do the following:
Person.where(name: 'John').or.where(last_name: 'Smith').all
Even more valuable is the ability to chain scopes with OR
:
scope :first_or_last_name, ->(name) { where(name: name.split(' ').first).or.where(last_name: name.split(' ').last) }
scope :parent_last_name, ->(name) { includes(:parents).where(last_name: name) }
Then you can find all Persons with first or last name or whose parent with last name
Person.first_or_last_name('John Smith').or.parent_last_name('Smith')
Not the best example for the use of this, but just trying to fit it with the question.
2
Which version or Rails do you need for this?
– Sash
May 31 '15 at 11:44
3
The latest discussion and the pull request that will make this into Rails core can be found here: github.com/rails/rails/pull/16052 Rails 5.0 is targeted for the official release of the.or
chain functionality. I was able to use the monkey patch I mentioned on Rails >= 3.2; however you may want to wait for Rails 5 to introduce any long-standing changes to your code.
– codenamev
Jun 1 '15 at 12:31
1
Yep, it was merged and released with Rails 5.
– amoebe
Dec 2 '16 at 15:21
add a comment |
You can also use MetaWhere gem to not mix up your code with SQL stuff:
Person.where((:name => "John") | (:lastname => "Smith"))
good call on this one
– Nick Vanderbilt
Sep 13 '10 at 1:31
3
+1. The successor to MetaWhere is squeel by the same author.
– Thilo
Dec 22 '12 at 19:22
add a comment |
This would be a good candidate for MetaWhere if you're using Rails 3.0+, but it doesn't work on Rails 3.1. You might want to try out squeel instead. It's made by the same author. Here's how'd you'd perform an OR based chain:
Person.where{(name == "John") | (lastname == "Smith")}
You can mix and match AND/OR, among many other awesome things.
add a comment |
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')
5
Not supported in Rails 4.2.5
– fatuhoku
Jul 29 '16 at 14:44
Foo.where(foo: 'bar1').or.where(bar: 'bar2')
does not work. It should be Foo.where(foo: 'bar1').or.where(Foo.where(bar: 'bar2'))
– Ana María Martínez Gómez
Nov 28 '18 at 13:42
add a comment |
For me (Rails 4.2.5) it only works like this:
{ where("name = ? or name = ?", a, b) }
add a comment |
Rails 4 + Scope + Arel
class Creature < ActiveRecord::Base
scope :is_good_pet, -> {
where(
arel_table[:is_cat].eq(true)
.or(arel_table[:is_dog].eq(true))
.or(arel_table[:eats_children].eq(false))
)
}
end
I tried chaining named scopes with .or and no luck, but this worked for finding anything with those booleans set. Generates SQL like
SELECT 'CREATURES'.* FROM 'CREATURES' WHERE ((('CREATURES'.'is_cat' = 1 OR 'CREATURES'.'is_dog' = 1) OR 'CREATURES'.'eats_children' = 0))
add a comment |
Rails 4
scope :combined_scope, -> { where("name = ? or name = ?", 'a', 'b') }
add a comment |
If you can't write out the where clause manually to include the "or" statement (ie, you want to combine two scopes), you can use union:
Model.find_by_sql("#{Model.scope1.to_sql} UNION #{Model.scope2.to_sql}")
(source: ActiveRecord Query Union)
This is will return all records matching either query. However, this returns an array, not an arel. If you really want to return an arel, you checkout this gist: https://gist.github.com/j-mcnally/250eaaceef234dd8971b.
This will do the job, as long as you don't mind monkey patching rails.
add a comment |
Also see these related questions: here, here and here
For rails 4, based on this article and this original answer
Person
.unscoped # See the caution note below. Maybe you want default scope here, in which case just remove this line.
.where( # Begin a where clause
where(:name => "John").where(:lastname => "Smith") # join the scopes to be OR'd
.where_values # get an array of arel where clause conditions based on the chain thus far
.inject(:or) # inject the OR operator into the arels
# ^^ Inject may not work in Rails3. But this should work instead:
.joins(" OR ")
# ^^ Remember to only use .inject or .joins, not both
) # Resurface the arels inside the overarching query
Note the article's caution at the end:
Rails 4.1+
Rails 4.1 treats default_scope just as a regular scope. The default
scope (if you have any) is included in the where_values result and
inject(:or) will add or statement between the default scope and your
wheres. That's bad.
To solve that, you just need to unscope the query.
add a comment |
the squeel
gem provides an incredibly easy way to accomplish this (prior to this I used something like @coloradoblue's method):
names = ["Kroger", "Walmart", "Target", "Aldi"]
matching_stores = Grocery.where{name.like_any(names)}
add a comment |
So the answer to the original question, can you join scopes with 'or' instead of 'and' seems to be "no you can't". But you can hand code a completely different scope or query that does the job, or use a different framework from ActiveRecord e.g. MetaWhere or Squeel. Not useful in my case
I'm 'or'ing a scope generated by pg_search, which does a bit more than select, it includes order by ASC, which makes a mess of a clean union. I want to 'or' it with a handcrafted scope that does stuff I can't do in pg_search. So I've had to do it like this.
Product.find_by_sql("(#{Product.code_starts_with('Tom').to_sql}) union (#{Product.name_starts_with('Tom').to_sql})")
I.e. turn the scopes into sql, put brackets around each one, union them together and then find_by_sql using the sql generated. It's a bit rubbish, but it does work.
No, don't tell me I can use "against: [:name,:code]" in pg_search, I'd like to do it like that, but the 'name' field is an hstore, which pg_search can't handle yet. So the scope by name has to be hand crafted and then unioned with the pg_search scope.
add a comment |
If you're looking to provide a scope (instead of explicitly working on the whole dataset) here's what you should do with Rails 5:
scope :john_or_smith, -> { where(name: "John").or(where(lastname: "Smith")) }
Or:
def self.john_or_smith
where(name: "John").or(where(lastname: "Smith"))
end
This is correct, but a more literal answer than the same thing that stackoverflow.com/a/42894753/1032882 technically does.
– RudyOnRails
Jan 2 at 23:46
add a comment |
This is a very convenient way and it works fine in Rails 5:
Transaction
.where(transaction_type: ["Create", "Correspond"])
.or(
Transaction.where(
transaction_type: "Status",
field: "Status",
newvalue: ["resolved", "deleted"]
)
)
.or(
Transaction.where(transaction_type: "Set", field: "Queue")
)
add a comment |
names = ["tim", "tom", "bob", "alex"]
sql_string = names.map { |t| "name = '#{t}'" }.join(" OR ")
@people = People.where(sql_string)
4
this is vulnerable to sqlinjection...
– BvuRVKyUVlViVIc7
Jul 12 '13 at 18:57
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3684311%2frails-how-to-chain-scope-queries-with-or-instead-of-and%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
19 Answers
19
active
oldest
votes
19 Answers
19
active
oldest
votes
active
oldest
votes
active
oldest
votes
You would do
Person.where('name=? OR lastname=?', 'John', 'Smith')
Right now, there isn't any other OR support by the new AR3 syntax (that is without using some 3rd party gem).
21
and just for safety's sake, it's worth expressing this as Person.where("name = ? OR lastname = ?", 'John', 'Smith')
– CambridgeMike
Nov 9 '11 at 3:55
6
This is still applicable in Rails 4? Nothing better came up in Rails 4?
– Donato
Apr 4 '15 at 21:18
11
No change in Rails 4, but Rails 5 will have.or
built in.
– lime
Jun 11 '15 at 6:53
3
this are not scopes, are just 2 where clauses, or a very specific scope case. What if I would like to chain more complex scopes, with joins for instance.
– miguelfg
Oct 22 '15 at 11:47
2
With Rails 5 you can also do something like, Person.where("name = 'John'").or(Person.where("lastname = 'Smith'"))
– shyam
Sep 28 '17 at 7:19
add a comment |
You would do
Person.where('name=? OR lastname=?', 'John', 'Smith')
Right now, there isn't any other OR support by the new AR3 syntax (that is without using some 3rd party gem).
21
and just for safety's sake, it's worth expressing this as Person.where("name = ? OR lastname = ?", 'John', 'Smith')
– CambridgeMike
Nov 9 '11 at 3:55
6
This is still applicable in Rails 4? Nothing better came up in Rails 4?
– Donato
Apr 4 '15 at 21:18
11
No change in Rails 4, but Rails 5 will have.or
built in.
– lime
Jun 11 '15 at 6:53
3
this are not scopes, are just 2 where clauses, or a very specific scope case. What if I would like to chain more complex scopes, with joins for instance.
– miguelfg
Oct 22 '15 at 11:47
2
With Rails 5 you can also do something like, Person.where("name = 'John'").or(Person.where("lastname = 'Smith'"))
– shyam
Sep 28 '17 at 7:19
add a comment |
You would do
Person.where('name=? OR lastname=?', 'John', 'Smith')
Right now, there isn't any other OR support by the new AR3 syntax (that is without using some 3rd party gem).
You would do
Person.where('name=? OR lastname=?', 'John', 'Smith')
Right now, there isn't any other OR support by the new AR3 syntax (that is without using some 3rd party gem).
edited May 9 '13 at 18:41
maerics
107k29205251
107k29205251
answered Sep 10 '10 at 12:38
PetrosPetros
7,48322630
7,48322630
21
and just for safety's sake, it's worth expressing this as Person.where("name = ? OR lastname = ?", 'John', 'Smith')
– CambridgeMike
Nov 9 '11 at 3:55
6
This is still applicable in Rails 4? Nothing better came up in Rails 4?
– Donato
Apr 4 '15 at 21:18
11
No change in Rails 4, but Rails 5 will have.or
built in.
– lime
Jun 11 '15 at 6:53
3
this are not scopes, are just 2 where clauses, or a very specific scope case. What if I would like to chain more complex scopes, with joins for instance.
– miguelfg
Oct 22 '15 at 11:47
2
With Rails 5 you can also do something like, Person.where("name = 'John'").or(Person.where("lastname = 'Smith'"))
– shyam
Sep 28 '17 at 7:19
add a comment |
21
and just for safety's sake, it's worth expressing this as Person.where("name = ? OR lastname = ?", 'John', 'Smith')
– CambridgeMike
Nov 9 '11 at 3:55
6
This is still applicable in Rails 4? Nothing better came up in Rails 4?
– Donato
Apr 4 '15 at 21:18
11
No change in Rails 4, but Rails 5 will have.or
built in.
– lime
Jun 11 '15 at 6:53
3
this are not scopes, are just 2 where clauses, or a very specific scope case. What if I would like to chain more complex scopes, with joins for instance.
– miguelfg
Oct 22 '15 at 11:47
2
With Rails 5 you can also do something like, Person.where("name = 'John'").or(Person.where("lastname = 'Smith'"))
– shyam
Sep 28 '17 at 7:19
21
21
and just for safety's sake, it's worth expressing this as Person.where("name = ? OR lastname = ?", 'John', 'Smith')
– CambridgeMike
Nov 9 '11 at 3:55
and just for safety's sake, it's worth expressing this as Person.where("name = ? OR lastname = ?", 'John', 'Smith')
– CambridgeMike
Nov 9 '11 at 3:55
6
6
This is still applicable in Rails 4? Nothing better came up in Rails 4?
– Donato
Apr 4 '15 at 21:18
This is still applicable in Rails 4? Nothing better came up in Rails 4?
– Donato
Apr 4 '15 at 21:18
11
11
No change in Rails 4, but Rails 5 will have
.or
built in.– lime
Jun 11 '15 at 6:53
No change in Rails 4, but Rails 5 will have
.or
built in.– lime
Jun 11 '15 at 6:53
3
3
this are not scopes, are just 2 where clauses, or a very specific scope case. What if I would like to chain more complex scopes, with joins for instance.
– miguelfg
Oct 22 '15 at 11:47
this are not scopes, are just 2 where clauses, or a very specific scope case. What if I would like to chain more complex scopes, with joins for instance.
– miguelfg
Oct 22 '15 at 11:47
2
2
With Rails 5 you can also do something like, Person.where("name = 'John'").or(Person.where("lastname = 'Smith'"))
– shyam
Sep 28 '17 at 7:19
With Rails 5 you can also do something like, Person.where("name = 'John'").or(Person.where("lastname = 'Smith'"))
– shyam
Sep 28 '17 at 7:19
add a comment |
Use ARel
t = Person.arel_table
results = Person.where(
t[:name].eq("John").
or(t[:lastname].eq("Smith"))
)
1
Can anybody comment on whether this type of query breaks in Postgres?
– Olivier Lacan
Oct 28 '11 at 17:20
2
I'm using Postgres and this seemed to work fine.
– MrTheWalrus
Dec 7 '11 at 16:45
ARel is supposed to be DB-agnostic.
– Simon Perepelitsa
Jul 27 '12 at 16:17
While this looks like a good idea, ARel is not a public API and using this may break your app in unexpected ways, so I'd advise against it unless you pay close attention to the evolution of the ARel API.
– Olivier Lacan
Aug 28 '14 at 3:45
7
@OlivierLacan Arel is a public API, or more precisely, it exposes one. Active Record just provides convenience methods that use it under the hood, It's completely valid to use it on it's own. It follows semantic versioning, so unless you are changing major versions (3.x.x => 4.x.x), there is no need to worry about breaking changes.
– Gray
Sep 30 '14 at 13:46
add a comment |
Use ARel
t = Person.arel_table
results = Person.where(
t[:name].eq("John").
or(t[:lastname].eq("Smith"))
)
1
Can anybody comment on whether this type of query breaks in Postgres?
– Olivier Lacan
Oct 28 '11 at 17:20
2
I'm using Postgres and this seemed to work fine.
– MrTheWalrus
Dec 7 '11 at 16:45
ARel is supposed to be DB-agnostic.
– Simon Perepelitsa
Jul 27 '12 at 16:17
While this looks like a good idea, ARel is not a public API and using this may break your app in unexpected ways, so I'd advise against it unless you pay close attention to the evolution of the ARel API.
– Olivier Lacan
Aug 28 '14 at 3:45
7
@OlivierLacan Arel is a public API, or more precisely, it exposes one. Active Record just provides convenience methods that use it under the hood, It's completely valid to use it on it's own. It follows semantic versioning, so unless you are changing major versions (3.x.x => 4.x.x), there is no need to worry about breaking changes.
– Gray
Sep 30 '14 at 13:46
add a comment |
Use ARel
t = Person.arel_table
results = Person.where(
t[:name].eq("John").
or(t[:lastname].eq("Smith"))
)
Use ARel
t = Person.arel_table
results = Person.where(
t[:name].eq("John").
or(t[:lastname].eq("Smith"))
)
answered Sep 10 '10 at 12:57
Dan McNevinDan McNevin
20.9k43128
20.9k43128
1
Can anybody comment on whether this type of query breaks in Postgres?
– Olivier Lacan
Oct 28 '11 at 17:20
2
I'm using Postgres and this seemed to work fine.
– MrTheWalrus
Dec 7 '11 at 16:45
ARel is supposed to be DB-agnostic.
– Simon Perepelitsa
Jul 27 '12 at 16:17
While this looks like a good idea, ARel is not a public API and using this may break your app in unexpected ways, so I'd advise against it unless you pay close attention to the evolution of the ARel API.
– Olivier Lacan
Aug 28 '14 at 3:45
7
@OlivierLacan Arel is a public API, or more precisely, it exposes one. Active Record just provides convenience methods that use it under the hood, It's completely valid to use it on it's own. It follows semantic versioning, so unless you are changing major versions (3.x.x => 4.x.x), there is no need to worry about breaking changes.
– Gray
Sep 30 '14 at 13:46
add a comment |
1
Can anybody comment on whether this type of query breaks in Postgres?
– Olivier Lacan
Oct 28 '11 at 17:20
2
I'm using Postgres and this seemed to work fine.
– MrTheWalrus
Dec 7 '11 at 16:45
ARel is supposed to be DB-agnostic.
– Simon Perepelitsa
Jul 27 '12 at 16:17
While this looks like a good idea, ARel is not a public API and using this may break your app in unexpected ways, so I'd advise against it unless you pay close attention to the evolution of the ARel API.
– Olivier Lacan
Aug 28 '14 at 3:45
7
@OlivierLacan Arel is a public API, or more precisely, it exposes one. Active Record just provides convenience methods that use it under the hood, It's completely valid to use it on it's own. It follows semantic versioning, so unless you are changing major versions (3.x.x => 4.x.x), there is no need to worry about breaking changes.
– Gray
Sep 30 '14 at 13:46
1
1
Can anybody comment on whether this type of query breaks in Postgres?
– Olivier Lacan
Oct 28 '11 at 17:20
Can anybody comment on whether this type of query breaks in Postgres?
– Olivier Lacan
Oct 28 '11 at 17:20
2
2
I'm using Postgres and this seemed to work fine.
– MrTheWalrus
Dec 7 '11 at 16:45
I'm using Postgres and this seemed to work fine.
– MrTheWalrus
Dec 7 '11 at 16:45
ARel is supposed to be DB-agnostic.
– Simon Perepelitsa
Jul 27 '12 at 16:17
ARel is supposed to be DB-agnostic.
– Simon Perepelitsa
Jul 27 '12 at 16:17
While this looks like a good idea, ARel is not a public API and using this may break your app in unexpected ways, so I'd advise against it unless you pay close attention to the evolution of the ARel API.
– Olivier Lacan
Aug 28 '14 at 3:45
While this looks like a good idea, ARel is not a public API and using this may break your app in unexpected ways, so I'd advise against it unless you pay close attention to the evolution of the ARel API.
– Olivier Lacan
Aug 28 '14 at 3:45
7
7
@OlivierLacan Arel is a public API, or more precisely, it exposes one. Active Record just provides convenience methods that use it under the hood, It's completely valid to use it on it's own. It follows semantic versioning, so unless you are changing major versions (3.x.x => 4.x.x), there is no need to worry about breaking changes.
– Gray
Sep 30 '14 at 13:46
@OlivierLacan Arel is a public API, or more precisely, it exposes one. Active Record just provides convenience methods that use it under the hood, It's completely valid to use it on it's own. It follows semantic versioning, so unless you are changing major versions (3.x.x => 4.x.x), there is no need to worry about breaking changes.
– Gray
Sep 30 '14 at 13:46
add a comment |
According to this pull request, Rails 5 now supports the following syntax for chaining queries:
Post.where(id: 1).or(Post.where(id: 2))
There's also a backport of the functionality into Rails 4.2 via this gem.
add a comment |
According to this pull request, Rails 5 now supports the following syntax for chaining queries:
Post.where(id: 1).or(Post.where(id: 2))
There's also a backport of the functionality into Rails 4.2 via this gem.
add a comment |
According to this pull request, Rails 5 now supports the following syntax for chaining queries:
Post.where(id: 1).or(Post.where(id: 2))
There's also a backport of the functionality into Rails 4.2 via this gem.
According to this pull request, Rails 5 now supports the following syntax for chaining queries:
Post.where(id: 1).or(Post.where(id: 2))
There's also a backport of the functionality into Rails 4.2 via this gem.
answered Mar 20 '17 at 2:05
Ryan LeafRyan Leaf
53157
53157
add a comment |
add a comment |
Update for Rails4
requires no 3rd party gems
a = Person.where(name: "John") # or any scope
b = Person.where(lastname: "Smith") # or any scope
Person.where([a, b].map{|s| s.arel.constraints.reduce(:and) }.reduce(:or))
.tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
Old answer
requires no 3rd party gems
Person.where(
Person.where(:name => "John").where(:lastname => "Smith")
.where_values.reduce(:or)
)
5
this is really the only pure answer to the OP's question in terms of resources and method. the other answers either (a) require 3rd party apis or (b) require interpolatingor
or other operators within a text block, neither of which is reflected in OP's code.
– allenwlee
Feb 12 '15 at 21:24
6
here's a decent article explaining it coderwall.com/p/dgv7ag/…
– allenwlee
Feb 12 '15 at 21:37
4
Used...where_values.join(' OR ')
in my case
– Sash
May 31 '15 at 17:56
5
How does this work in scopes?
– baash05
Jul 20 '15 at 2:20
2
You can omit the.tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
part if your scopes don't have any variables that need binding.
– fatuhoku
May 10 '16 at 12:44
add a comment |
Update for Rails4
requires no 3rd party gems
a = Person.where(name: "John") # or any scope
b = Person.where(lastname: "Smith") # or any scope
Person.where([a, b].map{|s| s.arel.constraints.reduce(:and) }.reduce(:or))
.tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
Old answer
requires no 3rd party gems
Person.where(
Person.where(:name => "John").where(:lastname => "Smith")
.where_values.reduce(:or)
)
5
this is really the only pure answer to the OP's question in terms of resources and method. the other answers either (a) require 3rd party apis or (b) require interpolatingor
or other operators within a text block, neither of which is reflected in OP's code.
– allenwlee
Feb 12 '15 at 21:24
6
here's a decent article explaining it coderwall.com/p/dgv7ag/…
– allenwlee
Feb 12 '15 at 21:37
4
Used...where_values.join(' OR ')
in my case
– Sash
May 31 '15 at 17:56
5
How does this work in scopes?
– baash05
Jul 20 '15 at 2:20
2
You can omit the.tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
part if your scopes don't have any variables that need binding.
– fatuhoku
May 10 '16 at 12:44
add a comment |
Update for Rails4
requires no 3rd party gems
a = Person.where(name: "John") # or any scope
b = Person.where(lastname: "Smith") # or any scope
Person.where([a, b].map{|s| s.arel.constraints.reduce(:and) }.reduce(:or))
.tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
Old answer
requires no 3rd party gems
Person.where(
Person.where(:name => "John").where(:lastname => "Smith")
.where_values.reduce(:or)
)
Update for Rails4
requires no 3rd party gems
a = Person.where(name: "John") # or any scope
b = Person.where(lastname: "Smith") # or any scope
Person.where([a, b].map{|s| s.arel.constraints.reduce(:and) }.reduce(:or))
.tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
Old answer
requires no 3rd party gems
Person.where(
Person.where(:name => "John").where(:lastname => "Smith")
.where_values.reduce(:or)
)
edited Nov 26 '15 at 3:39
answered Nov 21 '14 at 12:01
kissrobberkissrobber
517412
517412
5
this is really the only pure answer to the OP's question in terms of resources and method. the other answers either (a) require 3rd party apis or (b) require interpolatingor
or other operators within a text block, neither of which is reflected in OP's code.
– allenwlee
Feb 12 '15 at 21:24
6
here's a decent article explaining it coderwall.com/p/dgv7ag/…
– allenwlee
Feb 12 '15 at 21:37
4
Used...where_values.join(' OR ')
in my case
– Sash
May 31 '15 at 17:56
5
How does this work in scopes?
– baash05
Jul 20 '15 at 2:20
2
You can omit the.tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
part if your scopes don't have any variables that need binding.
– fatuhoku
May 10 '16 at 12:44
add a comment |
5
this is really the only pure answer to the OP's question in terms of resources and method. the other answers either (a) require 3rd party apis or (b) require interpolatingor
or other operators within a text block, neither of which is reflected in OP's code.
– allenwlee
Feb 12 '15 at 21:24
6
here's a decent article explaining it coderwall.com/p/dgv7ag/…
– allenwlee
Feb 12 '15 at 21:37
4
Used...where_values.join(' OR ')
in my case
– Sash
May 31 '15 at 17:56
5
How does this work in scopes?
– baash05
Jul 20 '15 at 2:20
2
You can omit the.tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
part if your scopes don't have any variables that need binding.
– fatuhoku
May 10 '16 at 12:44
5
5
this is really the only pure answer to the OP's question in terms of resources and method. the other answers either (a) require 3rd party apis or (b) require interpolating
or
or other operators within a text block, neither of which is reflected in OP's code.– allenwlee
Feb 12 '15 at 21:24
this is really the only pure answer to the OP's question in terms of resources and method. the other answers either (a) require 3rd party apis or (b) require interpolating
or
or other operators within a text block, neither of which is reflected in OP's code.– allenwlee
Feb 12 '15 at 21:24
6
6
here's a decent article explaining it coderwall.com/p/dgv7ag/…
– allenwlee
Feb 12 '15 at 21:37
here's a decent article explaining it coderwall.com/p/dgv7ag/…
– allenwlee
Feb 12 '15 at 21:37
4
4
Used
...where_values.join(' OR ')
in my case– Sash
May 31 '15 at 17:56
Used
...where_values.join(' OR ')
in my case– Sash
May 31 '15 at 17:56
5
5
How does this work in scopes?
– baash05
Jul 20 '15 at 2:20
How does this work in scopes?
– baash05
Jul 20 '15 at 2:20
2
2
You can omit the
.tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
part if your scopes don't have any variables that need binding.– fatuhoku
May 10 '16 at 12:44
You can omit the
.tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
part if your scopes don't have any variables that need binding.– fatuhoku
May 10 '16 at 12:44
add a comment |
Just posting the Array syntax for same column OR queries to help peeps out.
Person.where(name: ["John", "Steve"])
2
The question check John against name and Smith against lastname
– steven_noble
Aug 8 '15 at 1:21
11
@steven_noble - that's why I bolded "same column" with the or query. I can delete the comment altogether, but thought it would be helpful for people perusing "or" query SO questions.
– daino3
Aug 10 '15 at 19:19
add a comment |
Just posting the Array syntax for same column OR queries to help peeps out.
Person.where(name: ["John", "Steve"])
2
The question check John against name and Smith against lastname
– steven_noble
Aug 8 '15 at 1:21
11
@steven_noble - that's why I bolded "same column" with the or query. I can delete the comment altogether, but thought it would be helpful for people perusing "or" query SO questions.
– daino3
Aug 10 '15 at 19:19
add a comment |
Just posting the Array syntax for same column OR queries to help peeps out.
Person.where(name: ["John", "Steve"])
Just posting the Array syntax for same column OR queries to help peeps out.
Person.where(name: ["John", "Steve"])
answered Jul 24 '15 at 21:30
daino3daino3
1,9611628
1,9611628
2
The question check John against name and Smith against lastname
– steven_noble
Aug 8 '15 at 1:21
11
@steven_noble - that's why I bolded "same column" with the or query. I can delete the comment altogether, but thought it would be helpful for people perusing "or" query SO questions.
– daino3
Aug 10 '15 at 19:19
add a comment |
2
The question check John against name and Smith against lastname
– steven_noble
Aug 8 '15 at 1:21
11
@steven_noble - that's why I bolded "same column" with the or query. I can delete the comment altogether, but thought it would be helpful for people perusing "or" query SO questions.
– daino3
Aug 10 '15 at 19:19
2
2
The question check John against name and Smith against lastname
– steven_noble
Aug 8 '15 at 1:21
The question check John against name and Smith against lastname
– steven_noble
Aug 8 '15 at 1:21
11
11
@steven_noble - that's why I bolded "same column" with the or query. I can delete the comment altogether, but thought it would be helpful for people perusing "or" query SO questions.
– daino3
Aug 10 '15 at 19:19
@steven_noble - that's why I bolded "same column" with the or query. I can delete the comment altogether, but thought it would be helpful for people perusing "or" query SO questions.
– daino3
Aug 10 '15 at 19:19
add a comment |
In case anyone is looking for an updated answer to this one, it looks like there is an existing pull request to get this into Rails: https://github.com/rails/rails/pull/9052.
Thanks to @j-mcnally's monkey patch for ActiveRecord (https://gist.github.com/j-mcnally/250eaaceef234dd8971b) you can do the following:
Person.where(name: 'John').or.where(last_name: 'Smith').all
Even more valuable is the ability to chain scopes with OR
:
scope :first_or_last_name, ->(name) { where(name: name.split(' ').first).or.where(last_name: name.split(' ').last) }
scope :parent_last_name, ->(name) { includes(:parents).where(last_name: name) }
Then you can find all Persons with first or last name or whose parent with last name
Person.first_or_last_name('John Smith').or.parent_last_name('Smith')
Not the best example for the use of this, but just trying to fit it with the question.
2
Which version or Rails do you need for this?
– Sash
May 31 '15 at 11:44
3
The latest discussion and the pull request that will make this into Rails core can be found here: github.com/rails/rails/pull/16052 Rails 5.0 is targeted for the official release of the.or
chain functionality. I was able to use the monkey patch I mentioned on Rails >= 3.2; however you may want to wait for Rails 5 to introduce any long-standing changes to your code.
– codenamev
Jun 1 '15 at 12:31
1
Yep, it was merged and released with Rails 5.
– amoebe
Dec 2 '16 at 15:21
add a comment |
In case anyone is looking for an updated answer to this one, it looks like there is an existing pull request to get this into Rails: https://github.com/rails/rails/pull/9052.
Thanks to @j-mcnally's monkey patch for ActiveRecord (https://gist.github.com/j-mcnally/250eaaceef234dd8971b) you can do the following:
Person.where(name: 'John').or.where(last_name: 'Smith').all
Even more valuable is the ability to chain scopes with OR
:
scope :first_or_last_name, ->(name) { where(name: name.split(' ').first).or.where(last_name: name.split(' ').last) }
scope :parent_last_name, ->(name) { includes(:parents).where(last_name: name) }
Then you can find all Persons with first or last name or whose parent with last name
Person.first_or_last_name('John Smith').or.parent_last_name('Smith')
Not the best example for the use of this, but just trying to fit it with the question.
2
Which version or Rails do you need for this?
– Sash
May 31 '15 at 11:44
3
The latest discussion and the pull request that will make this into Rails core can be found here: github.com/rails/rails/pull/16052 Rails 5.0 is targeted for the official release of the.or
chain functionality. I was able to use the monkey patch I mentioned on Rails >= 3.2; however you may want to wait for Rails 5 to introduce any long-standing changes to your code.
– codenamev
Jun 1 '15 at 12:31
1
Yep, it was merged and released with Rails 5.
– amoebe
Dec 2 '16 at 15:21
add a comment |
In case anyone is looking for an updated answer to this one, it looks like there is an existing pull request to get this into Rails: https://github.com/rails/rails/pull/9052.
Thanks to @j-mcnally's monkey patch for ActiveRecord (https://gist.github.com/j-mcnally/250eaaceef234dd8971b) you can do the following:
Person.where(name: 'John').or.where(last_name: 'Smith').all
Even more valuable is the ability to chain scopes with OR
:
scope :first_or_last_name, ->(name) { where(name: name.split(' ').first).or.where(last_name: name.split(' ').last) }
scope :parent_last_name, ->(name) { includes(:parents).where(last_name: name) }
Then you can find all Persons with first or last name or whose parent with last name
Person.first_or_last_name('John Smith').or.parent_last_name('Smith')
Not the best example for the use of this, but just trying to fit it with the question.
In case anyone is looking for an updated answer to this one, it looks like there is an existing pull request to get this into Rails: https://github.com/rails/rails/pull/9052.
Thanks to @j-mcnally's monkey patch for ActiveRecord (https://gist.github.com/j-mcnally/250eaaceef234dd8971b) you can do the following:
Person.where(name: 'John').or.where(last_name: 'Smith').all
Even more valuable is the ability to chain scopes with OR
:
scope :first_or_last_name, ->(name) { where(name: name.split(' ').first).or.where(last_name: name.split(' ').last) }
scope :parent_last_name, ->(name) { includes(:parents).where(last_name: name) }
Then you can find all Persons with first or last name or whose parent with last name
Person.first_or_last_name('John Smith').or.parent_last_name('Smith')
Not the best example for the use of this, but just trying to fit it with the question.
answered Aug 12 '13 at 16:47
codenamevcodenamev
1,5431220
1,5431220
2
Which version or Rails do you need for this?
– Sash
May 31 '15 at 11:44
3
The latest discussion and the pull request that will make this into Rails core can be found here: github.com/rails/rails/pull/16052 Rails 5.0 is targeted for the official release of the.or
chain functionality. I was able to use the monkey patch I mentioned on Rails >= 3.2; however you may want to wait for Rails 5 to introduce any long-standing changes to your code.
– codenamev
Jun 1 '15 at 12:31
1
Yep, it was merged and released with Rails 5.
– amoebe
Dec 2 '16 at 15:21
add a comment |
2
Which version or Rails do you need for this?
– Sash
May 31 '15 at 11:44
3
The latest discussion and the pull request that will make this into Rails core can be found here: github.com/rails/rails/pull/16052 Rails 5.0 is targeted for the official release of the.or
chain functionality. I was able to use the monkey patch I mentioned on Rails >= 3.2; however you may want to wait for Rails 5 to introduce any long-standing changes to your code.
– codenamev
Jun 1 '15 at 12:31
1
Yep, it was merged and released with Rails 5.
– amoebe
Dec 2 '16 at 15:21
2
2
Which version or Rails do you need for this?
– Sash
May 31 '15 at 11:44
Which version or Rails do you need for this?
– Sash
May 31 '15 at 11:44
3
3
The latest discussion and the pull request that will make this into Rails core can be found here: github.com/rails/rails/pull/16052 Rails 5.0 is targeted for the official release of the
.or
chain functionality. I was able to use the monkey patch I mentioned on Rails >= 3.2; however you may want to wait for Rails 5 to introduce any long-standing changes to your code.– codenamev
Jun 1 '15 at 12:31
The latest discussion and the pull request that will make this into Rails core can be found here: github.com/rails/rails/pull/16052 Rails 5.0 is targeted for the official release of the
.or
chain functionality. I was able to use the monkey patch I mentioned on Rails >= 3.2; however you may want to wait for Rails 5 to introduce any long-standing changes to your code.– codenamev
Jun 1 '15 at 12:31
1
1
Yep, it was merged and released with Rails 5.
– amoebe
Dec 2 '16 at 15:21
Yep, it was merged and released with Rails 5.
– amoebe
Dec 2 '16 at 15:21
add a comment |
You can also use MetaWhere gem to not mix up your code with SQL stuff:
Person.where((:name => "John") | (:lastname => "Smith"))
good call on this one
– Nick Vanderbilt
Sep 13 '10 at 1:31
3
+1. The successor to MetaWhere is squeel by the same author.
– Thilo
Dec 22 '12 at 19:22
add a comment |
You can also use MetaWhere gem to not mix up your code with SQL stuff:
Person.where((:name => "John") | (:lastname => "Smith"))
good call on this one
– Nick Vanderbilt
Sep 13 '10 at 1:31
3
+1. The successor to MetaWhere is squeel by the same author.
– Thilo
Dec 22 '12 at 19:22
add a comment |
You can also use MetaWhere gem to not mix up your code with SQL stuff:
Person.where((:name => "John") | (:lastname => "Smith"))
You can also use MetaWhere gem to not mix up your code with SQL stuff:
Person.where((:name => "John") | (:lastname => "Smith"))
answered Sep 10 '10 at 15:14
Simon PerepelitsaSimon Perepelitsa
15.8k85170
15.8k85170
good call on this one
– Nick Vanderbilt
Sep 13 '10 at 1:31
3
+1. The successor to MetaWhere is squeel by the same author.
– Thilo
Dec 22 '12 at 19:22
add a comment |
good call on this one
– Nick Vanderbilt
Sep 13 '10 at 1:31
3
+1. The successor to MetaWhere is squeel by the same author.
– Thilo
Dec 22 '12 at 19:22
good call on this one
– Nick Vanderbilt
Sep 13 '10 at 1:31
good call on this one
– Nick Vanderbilt
Sep 13 '10 at 1:31
3
3
+1. The successor to MetaWhere is squeel by the same author.
– Thilo
Dec 22 '12 at 19:22
+1. The successor to MetaWhere is squeel by the same author.
– Thilo
Dec 22 '12 at 19:22
add a comment |
This would be a good candidate for MetaWhere if you're using Rails 3.0+, but it doesn't work on Rails 3.1. You might want to try out squeel instead. It's made by the same author. Here's how'd you'd perform an OR based chain:
Person.where{(name == "John") | (lastname == "Smith")}
You can mix and match AND/OR, among many other awesome things.
add a comment |
This would be a good candidate for MetaWhere if you're using Rails 3.0+, but it doesn't work on Rails 3.1. You might want to try out squeel instead. It's made by the same author. Here's how'd you'd perform an OR based chain:
Person.where{(name == "John") | (lastname == "Smith")}
You can mix and match AND/OR, among many other awesome things.
add a comment |
This would be a good candidate for MetaWhere if you're using Rails 3.0+, but it doesn't work on Rails 3.1. You might want to try out squeel instead. It's made by the same author. Here's how'd you'd perform an OR based chain:
Person.where{(name == "John") | (lastname == "Smith")}
You can mix and match AND/OR, among many other awesome things.
This would be a good candidate for MetaWhere if you're using Rails 3.0+, but it doesn't work on Rails 3.1. You might want to try out squeel instead. It's made by the same author. Here's how'd you'd perform an OR based chain:
Person.where{(name == "John") | (lastname == "Smith")}
You can mix and match AND/OR, among many other awesome things.
edited Feb 16 '13 at 22:42
answered Jan 12 '12 at 1:33
dhulihandhulihan
7,01483243
7,01483243
add a comment |
add a comment |
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')
5
Not supported in Rails 4.2.5
– fatuhoku
Jul 29 '16 at 14:44
Foo.where(foo: 'bar1').or.where(bar: 'bar2')
does not work. It should be Foo.where(foo: 'bar1').or.where(Foo.where(bar: 'bar2'))
– Ana María Martínez Gómez
Nov 28 '18 at 13:42
add a comment |
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')
5
Not supported in Rails 4.2.5
– fatuhoku
Jul 29 '16 at 14:44
Foo.where(foo: 'bar1').or.where(bar: 'bar2')
does not work. It should be Foo.where(foo: 'bar1').or.where(Foo.where(bar: 'bar2'))
– Ana María Martínez Gómez
Nov 28 '18 at 13:42
add a comment |
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')
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')
answered Dec 18 '14 at 10:55
Christian FazziniChristian Fazzini
12.3k1991196
12.3k1991196
5
Not supported in Rails 4.2.5
– fatuhoku
Jul 29 '16 at 14:44
Foo.where(foo: 'bar1').or.where(bar: 'bar2')
does not work. It should be Foo.where(foo: 'bar1').or.where(Foo.where(bar: 'bar2'))
– Ana María Martínez Gómez
Nov 28 '18 at 13:42
add a comment |
5
Not supported in Rails 4.2.5
– fatuhoku
Jul 29 '16 at 14:44
Foo.where(foo: 'bar1').or.where(bar: 'bar2')
does not work. It should be Foo.where(foo: 'bar1').or.where(Foo.where(bar: 'bar2'))
– Ana María Martínez Gómez
Nov 28 '18 at 13:42
5
5
Not supported in Rails 4.2.5
– fatuhoku
Jul 29 '16 at 14:44
Not supported in Rails 4.2.5
– fatuhoku
Jul 29 '16 at 14:44
Foo.where(foo: 'bar1').or.where(bar: 'bar2')
does not work. It should be Foo.where(foo: 'bar1').or.where(Foo.where(bar: 'bar2'))– Ana María Martínez Gómez
Nov 28 '18 at 13:42
Foo.where(foo: 'bar1').or.where(bar: 'bar2')
does not work. It should be Foo.where(foo: 'bar1').or.where(Foo.where(bar: 'bar2'))– Ana María Martínez Gómez
Nov 28 '18 at 13:42
add a comment |
For me (Rails 4.2.5) it only works like this:
{ where("name = ? or name = ?", a, b) }
add a comment |
For me (Rails 4.2.5) it only works like this:
{ where("name = ? or name = ?", a, b) }
add a comment |
For me (Rails 4.2.5) it only works like this:
{ where("name = ? or name = ?", a, b) }
For me (Rails 4.2.5) it only works like this:
{ where("name = ? or name = ?", a, b) }
answered Jun 29 '16 at 20:29
ZsoltZsolt
168112
168112
add a comment |
add a comment |
Rails 4 + Scope + Arel
class Creature < ActiveRecord::Base
scope :is_good_pet, -> {
where(
arel_table[:is_cat].eq(true)
.or(arel_table[:is_dog].eq(true))
.or(arel_table[:eats_children].eq(false))
)
}
end
I tried chaining named scopes with .or and no luck, but this worked for finding anything with those booleans set. Generates SQL like
SELECT 'CREATURES'.* FROM 'CREATURES' WHERE ((('CREATURES'.'is_cat' = 1 OR 'CREATURES'.'is_dog' = 1) OR 'CREATURES'.'eats_children' = 0))
add a comment |
Rails 4 + Scope + Arel
class Creature < ActiveRecord::Base
scope :is_good_pet, -> {
where(
arel_table[:is_cat].eq(true)
.or(arel_table[:is_dog].eq(true))
.or(arel_table[:eats_children].eq(false))
)
}
end
I tried chaining named scopes with .or and no luck, but this worked for finding anything with those booleans set. Generates SQL like
SELECT 'CREATURES'.* FROM 'CREATURES' WHERE ((('CREATURES'.'is_cat' = 1 OR 'CREATURES'.'is_dog' = 1) OR 'CREATURES'.'eats_children' = 0))
add a comment |
Rails 4 + Scope + Arel
class Creature < ActiveRecord::Base
scope :is_good_pet, -> {
where(
arel_table[:is_cat].eq(true)
.or(arel_table[:is_dog].eq(true))
.or(arel_table[:eats_children].eq(false))
)
}
end
I tried chaining named scopes with .or and no luck, but this worked for finding anything with those booleans set. Generates SQL like
SELECT 'CREATURES'.* FROM 'CREATURES' WHERE ((('CREATURES'.'is_cat' = 1 OR 'CREATURES'.'is_dog' = 1) OR 'CREATURES'.'eats_children' = 0))
Rails 4 + Scope + Arel
class Creature < ActiveRecord::Base
scope :is_good_pet, -> {
where(
arel_table[:is_cat].eq(true)
.or(arel_table[:is_dog].eq(true))
.or(arel_table[:eats_children].eq(false))
)
}
end
I tried chaining named scopes with .or and no luck, but this worked for finding anything with those booleans set. Generates SQL like
SELECT 'CREATURES'.* FROM 'CREATURES' WHERE ((('CREATURES'.'is_cat' = 1 OR 'CREATURES'.'is_dog' = 1) OR 'CREATURES'.'eats_children' = 0))
answered Jul 15 '14 at 21:12
genkilabsgenkilabs
2,2012032
2,2012032
add a comment |
add a comment |
Rails 4
scope :combined_scope, -> { where("name = ? or name = ?", 'a', 'b') }
add a comment |
Rails 4
scope :combined_scope, -> { where("name = ? or name = ?", 'a', 'b') }
add a comment |
Rails 4
scope :combined_scope, -> { where("name = ? or name = ?", 'a', 'b') }
Rails 4
scope :combined_scope, -> { where("name = ? or name = ?", 'a', 'b') }
answered May 19 '14 at 11:24
AbsAbs
3,07212226
3,07212226
add a comment |
add a comment |
If you can't write out the where clause manually to include the "or" statement (ie, you want to combine two scopes), you can use union:
Model.find_by_sql("#{Model.scope1.to_sql} UNION #{Model.scope2.to_sql}")
(source: ActiveRecord Query Union)
This is will return all records matching either query. However, this returns an array, not an arel. If you really want to return an arel, you checkout this gist: https://gist.github.com/j-mcnally/250eaaceef234dd8971b.
This will do the job, as long as you don't mind monkey patching rails.
add a comment |
If you can't write out the where clause manually to include the "or" statement (ie, you want to combine two scopes), you can use union:
Model.find_by_sql("#{Model.scope1.to_sql} UNION #{Model.scope2.to_sql}")
(source: ActiveRecord Query Union)
This is will return all records matching either query. However, this returns an array, not an arel. If you really want to return an arel, you checkout this gist: https://gist.github.com/j-mcnally/250eaaceef234dd8971b.
This will do the job, as long as you don't mind monkey patching rails.
add a comment |
If you can't write out the where clause manually to include the "or" statement (ie, you want to combine two scopes), you can use union:
Model.find_by_sql("#{Model.scope1.to_sql} UNION #{Model.scope2.to_sql}")
(source: ActiveRecord Query Union)
This is will return all records matching either query. However, this returns an array, not an arel. If you really want to return an arel, you checkout this gist: https://gist.github.com/j-mcnally/250eaaceef234dd8971b.
This will do the job, as long as you don't mind monkey patching rails.
If you can't write out the where clause manually to include the "or" statement (ie, you want to combine two scopes), you can use union:
Model.find_by_sql("#{Model.scope1.to_sql} UNION #{Model.scope2.to_sql}")
(source: ActiveRecord Query Union)
This is will return all records matching either query. However, this returns an array, not an arel. If you really want to return an arel, you checkout this gist: https://gist.github.com/j-mcnally/250eaaceef234dd8971b.
This will do the job, as long as you don't mind monkey patching rails.
edited May 23 '17 at 12:18
Community♦
11
11
answered Nov 29 '13 at 2:10
Jake ChristensenJake Christensen
397312
397312
add a comment |
add a comment |
Also see these related questions: here, here and here
For rails 4, based on this article and this original answer
Person
.unscoped # See the caution note below. Maybe you want default scope here, in which case just remove this line.
.where( # Begin a where clause
where(:name => "John").where(:lastname => "Smith") # join the scopes to be OR'd
.where_values # get an array of arel where clause conditions based on the chain thus far
.inject(:or) # inject the OR operator into the arels
# ^^ Inject may not work in Rails3. But this should work instead:
.joins(" OR ")
# ^^ Remember to only use .inject or .joins, not both
) # Resurface the arels inside the overarching query
Note the article's caution at the end:
Rails 4.1+
Rails 4.1 treats default_scope just as a regular scope. The default
scope (if you have any) is included in the where_values result and
inject(:or) will add or statement between the default scope and your
wheres. That's bad.
To solve that, you just need to unscope the query.
add a comment |
Also see these related questions: here, here and here
For rails 4, based on this article and this original answer
Person
.unscoped # See the caution note below. Maybe you want default scope here, in which case just remove this line.
.where( # Begin a where clause
where(:name => "John").where(:lastname => "Smith") # join the scopes to be OR'd
.where_values # get an array of arel where clause conditions based on the chain thus far
.inject(:or) # inject the OR operator into the arels
# ^^ Inject may not work in Rails3. But this should work instead:
.joins(" OR ")
# ^^ Remember to only use .inject or .joins, not both
) # Resurface the arels inside the overarching query
Note the article's caution at the end:
Rails 4.1+
Rails 4.1 treats default_scope just as a regular scope. The default
scope (if you have any) is included in the where_values result and
inject(:or) will add or statement between the default scope and your
wheres. That's bad.
To solve that, you just need to unscope the query.
add a comment |
Also see these related questions: here, here and here
For rails 4, based on this article and this original answer
Person
.unscoped # See the caution note below. Maybe you want default scope here, in which case just remove this line.
.where( # Begin a where clause
where(:name => "John").where(:lastname => "Smith") # join the scopes to be OR'd
.where_values # get an array of arel where clause conditions based on the chain thus far
.inject(:or) # inject the OR operator into the arels
# ^^ Inject may not work in Rails3. But this should work instead:
.joins(" OR ")
# ^^ Remember to only use .inject or .joins, not both
) # Resurface the arels inside the overarching query
Note the article's caution at the end:
Rails 4.1+
Rails 4.1 treats default_scope just as a regular scope. The default
scope (if you have any) is included in the where_values result and
inject(:or) will add or statement between the default scope and your
wheres. That's bad.
To solve that, you just need to unscope the query.
Also see these related questions: here, here and here
For rails 4, based on this article and this original answer
Person
.unscoped # See the caution note below. Maybe you want default scope here, in which case just remove this line.
.where( # Begin a where clause
where(:name => "John").where(:lastname => "Smith") # join the scopes to be OR'd
.where_values # get an array of arel where clause conditions based on the chain thus far
.inject(:or) # inject the OR operator into the arels
# ^^ Inject may not work in Rails3. But this should work instead:
.joins(" OR ")
# ^^ Remember to only use .inject or .joins, not both
) # Resurface the arels inside the overarching query
Note the article's caution at the end:
Rails 4.1+
Rails 4.1 treats default_scope just as a regular scope. The default
scope (if you have any) is included in the where_values result and
inject(:or) will add or statement between the default scope and your
wheres. That's bad.
To solve that, you just need to unscope the query.
edited May 23 '17 at 12:34
Community♦
11
11
answered Oct 26 '16 at 18:18
HeyZikoHeyZiko
1,0011016
1,0011016
add a comment |
add a comment |
the squeel
gem provides an incredibly easy way to accomplish this (prior to this I used something like @coloradoblue's method):
names = ["Kroger", "Walmart", "Target", "Aldi"]
matching_stores = Grocery.where{name.like_any(names)}
add a comment |
the squeel
gem provides an incredibly easy way to accomplish this (prior to this I used something like @coloradoblue's method):
names = ["Kroger", "Walmart", "Target", "Aldi"]
matching_stores = Grocery.where{name.like_any(names)}
add a comment |
the squeel
gem provides an incredibly easy way to accomplish this (prior to this I used something like @coloradoblue's method):
names = ["Kroger", "Walmart", "Target", "Aldi"]
matching_stores = Grocery.where{name.like_any(names)}
the squeel
gem provides an incredibly easy way to accomplish this (prior to this I used something like @coloradoblue's method):
names = ["Kroger", "Walmart", "Target", "Aldi"]
matching_stores = Grocery.where{name.like_any(names)}
answered Oct 3 '13 at 21:34
boulder_rubyboulder_ruby
27.3k65975
27.3k65975
add a comment |
add a comment |
So the answer to the original question, can you join scopes with 'or' instead of 'and' seems to be "no you can't". But you can hand code a completely different scope or query that does the job, or use a different framework from ActiveRecord e.g. MetaWhere or Squeel. Not useful in my case
I'm 'or'ing a scope generated by pg_search, which does a bit more than select, it includes order by ASC, which makes a mess of a clean union. I want to 'or' it with a handcrafted scope that does stuff I can't do in pg_search. So I've had to do it like this.
Product.find_by_sql("(#{Product.code_starts_with('Tom').to_sql}) union (#{Product.name_starts_with('Tom').to_sql})")
I.e. turn the scopes into sql, put brackets around each one, union them together and then find_by_sql using the sql generated. It's a bit rubbish, but it does work.
No, don't tell me I can use "against: [:name,:code]" in pg_search, I'd like to do it like that, but the 'name' field is an hstore, which pg_search can't handle yet. So the scope by name has to be hand crafted and then unioned with the pg_search scope.
add a comment |
So the answer to the original question, can you join scopes with 'or' instead of 'and' seems to be "no you can't". But you can hand code a completely different scope or query that does the job, or use a different framework from ActiveRecord e.g. MetaWhere or Squeel. Not useful in my case
I'm 'or'ing a scope generated by pg_search, which does a bit more than select, it includes order by ASC, which makes a mess of a clean union. I want to 'or' it with a handcrafted scope that does stuff I can't do in pg_search. So I've had to do it like this.
Product.find_by_sql("(#{Product.code_starts_with('Tom').to_sql}) union (#{Product.name_starts_with('Tom').to_sql})")
I.e. turn the scopes into sql, put brackets around each one, union them together and then find_by_sql using the sql generated. It's a bit rubbish, but it does work.
No, don't tell me I can use "against: [:name,:code]" in pg_search, I'd like to do it like that, but the 'name' field is an hstore, which pg_search can't handle yet. So the scope by name has to be hand crafted and then unioned with the pg_search scope.
add a comment |
So the answer to the original question, can you join scopes with 'or' instead of 'and' seems to be "no you can't". But you can hand code a completely different scope or query that does the job, or use a different framework from ActiveRecord e.g. MetaWhere or Squeel. Not useful in my case
I'm 'or'ing a scope generated by pg_search, which does a bit more than select, it includes order by ASC, which makes a mess of a clean union. I want to 'or' it with a handcrafted scope that does stuff I can't do in pg_search. So I've had to do it like this.
Product.find_by_sql("(#{Product.code_starts_with('Tom').to_sql}) union (#{Product.name_starts_with('Tom').to_sql})")
I.e. turn the scopes into sql, put brackets around each one, union them together and then find_by_sql using the sql generated. It's a bit rubbish, but it does work.
No, don't tell me I can use "against: [:name,:code]" in pg_search, I'd like to do it like that, but the 'name' field is an hstore, which pg_search can't handle yet. So the scope by name has to be hand crafted and then unioned with the pg_search scope.
So the answer to the original question, can you join scopes with 'or' instead of 'and' seems to be "no you can't". But you can hand code a completely different scope or query that does the job, or use a different framework from ActiveRecord e.g. MetaWhere or Squeel. Not useful in my case
I'm 'or'ing a scope generated by pg_search, which does a bit more than select, it includes order by ASC, which makes a mess of a clean union. I want to 'or' it with a handcrafted scope that does stuff I can't do in pg_search. So I've had to do it like this.
Product.find_by_sql("(#{Product.code_starts_with('Tom').to_sql}) union (#{Product.name_starts_with('Tom').to_sql})")
I.e. turn the scopes into sql, put brackets around each one, union them together and then find_by_sql using the sql generated. It's a bit rubbish, but it does work.
No, don't tell me I can use "against: [:name,:code]" in pg_search, I'd like to do it like that, but the 'name' field is an hstore, which pg_search can't handle yet. So the scope by name has to be hand crafted and then unioned with the pg_search scope.
answered Jul 10 '17 at 16:43
John SmallJohn Small
4761819
4761819
add a comment |
add a comment |
If you're looking to provide a scope (instead of explicitly working on the whole dataset) here's what you should do with Rails 5:
scope :john_or_smith, -> { where(name: "John").or(where(lastname: "Smith")) }
Or:
def self.john_or_smith
where(name: "John").or(where(lastname: "Smith"))
end
This is correct, but a more literal answer than the same thing that stackoverflow.com/a/42894753/1032882 technically does.
– RudyOnRails
Jan 2 at 23:46
add a comment |
If you're looking to provide a scope (instead of explicitly working on the whole dataset) here's what you should do with Rails 5:
scope :john_or_smith, -> { where(name: "John").or(where(lastname: "Smith")) }
Or:
def self.john_or_smith
where(name: "John").or(where(lastname: "Smith"))
end
This is correct, but a more literal answer than the same thing that stackoverflow.com/a/42894753/1032882 technically does.
– RudyOnRails
Jan 2 at 23:46
add a comment |
If you're looking to provide a scope (instead of explicitly working on the whole dataset) here's what you should do with Rails 5:
scope :john_or_smith, -> { where(name: "John").or(where(lastname: "Smith")) }
Or:
def self.john_or_smith
where(name: "John").or(where(lastname: "Smith"))
end
If you're looking to provide a scope (instead of explicitly working on the whole dataset) here's what you should do with Rails 5:
scope :john_or_smith, -> { where(name: "John").or(where(lastname: "Smith")) }
Or:
def self.john_or_smith
where(name: "John").or(where(lastname: "Smith"))
end
answered Nov 16 '18 at 12:00
thisismydesignthisismydesign
1,0281019
1,0281019
This is correct, but a more literal answer than the same thing that stackoverflow.com/a/42894753/1032882 technically does.
– RudyOnRails
Jan 2 at 23:46
add a comment |
This is correct, but a more literal answer than the same thing that stackoverflow.com/a/42894753/1032882 technically does.
– RudyOnRails
Jan 2 at 23:46
This is correct, but a more literal answer than the same thing that stackoverflow.com/a/42894753/1032882 technically does.
– RudyOnRails
Jan 2 at 23:46
This is correct, but a more literal answer than the same thing that stackoverflow.com/a/42894753/1032882 technically does.
– RudyOnRails
Jan 2 at 23:46
add a comment |
This is a very convenient way and it works fine in Rails 5:
Transaction
.where(transaction_type: ["Create", "Correspond"])
.or(
Transaction.where(
transaction_type: "Status",
field: "Status",
newvalue: ["resolved", "deleted"]
)
)
.or(
Transaction.where(transaction_type: "Set", field: "Queue")
)
add a comment |
This is a very convenient way and it works fine in Rails 5:
Transaction
.where(transaction_type: ["Create", "Correspond"])
.or(
Transaction.where(
transaction_type: "Status",
field: "Status",
newvalue: ["resolved", "deleted"]
)
)
.or(
Transaction.where(transaction_type: "Set", field: "Queue")
)
add a comment |
This is a very convenient way and it works fine in Rails 5:
Transaction
.where(transaction_type: ["Create", "Correspond"])
.or(
Transaction.where(
transaction_type: "Status",
field: "Status",
newvalue: ["resolved", "deleted"]
)
)
.or(
Transaction.where(transaction_type: "Set", field: "Queue")
)
This is a very convenient way and it works fine in Rails 5:
Transaction
.where(transaction_type: ["Create", "Correspond"])
.or(
Transaction.where(
transaction_type: "Status",
field: "Status",
newvalue: ["resolved", "deleted"]
)
)
.or(
Transaction.where(transaction_type: "Set", field: "Queue")
)
edited Mar 20 at 11:13
Maksim Kalmykov
93431220
93431220
answered Mar 6 at 10:16
Jigar BhattJigar Bhatt
1,5411626
1,5411626
add a comment |
add a comment |
names = ["tim", "tom", "bob", "alex"]
sql_string = names.map { |t| "name = '#{t}'" }.join(" OR ")
@people = People.where(sql_string)
4
this is vulnerable to sqlinjection...
– BvuRVKyUVlViVIc7
Jul 12 '13 at 18:57
add a comment |
names = ["tim", "tom", "bob", "alex"]
sql_string = names.map { |t| "name = '#{t}'" }.join(" OR ")
@people = People.where(sql_string)
4
this is vulnerable to sqlinjection...
– BvuRVKyUVlViVIc7
Jul 12 '13 at 18:57
add a comment |
names = ["tim", "tom", "bob", "alex"]
sql_string = names.map { |t| "name = '#{t}'" }.join(" OR ")
@people = People.where(sql_string)
names = ["tim", "tom", "bob", "alex"]
sql_string = names.map { |t| "name = '#{t}'" }.join(" OR ")
@people = People.where(sql_string)
answered Mar 11 '13 at 6:45
coloradobluecoloradoblue
571610
571610
4
this is vulnerable to sqlinjection...
– BvuRVKyUVlViVIc7
Jul 12 '13 at 18:57
add a comment |
4
this is vulnerable to sqlinjection...
– BvuRVKyUVlViVIc7
Jul 12 '13 at 18:57
4
4
this is vulnerable to sqlinjection...
– BvuRVKyUVlViVIc7
Jul 12 '13 at 18:57
this is vulnerable to sqlinjection...
– BvuRVKyUVlViVIc7
Jul 12 '13 at 18:57
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3684311%2frails-how-to-chain-scope-queries-with-or-instead-of-and%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown