Ruby-on-rails 如何在 ActiveRecord 查询中使用 OR 条件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10871131/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 03:29:24  来源:igfitidea点击:

How to use OR condition in ActiveRecord query

ruby-on-railsruby-on-rails-3activerecord

提问by Matt Elhotiby

I want to grab all the users that either have an email as the one supplied or the first and last name. So for example:

我想获取所有提供电子邮件或名字和姓氏的用户。例如:

users = User.where(:first_name => "James", :last_name => "Scott")

which will return all the users that have the first and last name of "James" & "Scott".

这将返回名字和姓氏为“James”和“Scott”的所有用户。

users = User.where(:email => "[email protected]")

which will return the user with the email as "[email protected]".

这将返回用户的电子邮件为“[email protected]”。

Is there a way to do a whereclause to return either the users with the same first and last name and the user with the email that matches in one wherequery or do I need to do a merge on the 2 separate whereclauses.

有没有办法做一个where子句来返回具有相同名字和姓氏的用户以及在一个where查询中匹配的电子邮件的用户,或者我是否需要对两个单独的where子句进行合并。

回答by Santhosh

Rails 5 comes with an ormethod.

Rails 5 附带了一个or方法

This method accepts an ActiveRecord::Relationobject. eg:

此方法接受一个ActiveRecord::Relation对象。例如:

User.where(first_name: 'James', last_name: 'Scott')
    .or(User.where(email: '[email protected]'))

回答by Anil

Try this:

尝试这个:

users = User.where("(first_name = 'James' and last_name = 'Scott') or email = '[email protected]'")

To interpolate variables:

插入变量:

users = User.where("(first_name = ? and last_name = ?) or email = ?", first_name, last_name, email)

回答by tokland

If you prefer a DSL approach (with no SQL), can use the underlying Arel layer:

如果您更喜欢 DSL 方法(没有 SQL),可以使用底层的 Arel 层:

t = User.arel_table
users = User.where(
  (t[:first_name].eq('Ernie').and(t[:last_name].eq('Scott')).
    or(t[:email].eq('james#gmail.com'))
)

That's a bit ugly, but if you use some wrapper over Arel (for example, this one), the code is much nicer:

这有点难看,但如果你在 Arel 上使用一些包装器(例如,这个),代码会更好:

users = User.where(
  ((User[:first_name] == 'Ernie') & (User[:last_name] == 'Scott')) |
   (User[:email] == 'james#gmail.com')
)

回答by DGM

If you don't want to write SQL as the others have mentioned, you could access the arel structures directly (looks like another answer has that) or use the squeelgem to do it much more elegantly:

如果你不想像其他人提到的那样编写 SQL,你可以直接访问 arel 结构(看起来另一个答案有)或者使用squeelgem 更优雅地完成它:

User.where{(first_name == 'Ernie') & (last_name == 'Scott') | (email == 'james#gmail.com')}

回答by ksol

You could use string conditions, as in Client.where("orders_count = ? AND locked = ?", params[:orders], false), and use ORin conjunction with AND. Be careful with the priority of those operators though.

您可以使用字符串条件,如Client.where("orders_count = ? AND locked = ?", params[:orders], false),并与OR结合使用AND。但是要注意这些运算符的优先级。

Cf Active Record Query Interface guide

参见Active Record 查询接口指南