ActiveRecord OR查询

pho*_*1re 178 ruby-on-rails ruby-on-rails-3 rails-activerecord

你如何在Rails 3 ActiveRecord中进行OR查询.我找到的所有示例都只有AND查询.

编辑:自Rails 5以来可以使用OR方法.请参阅ActiveRecord :: QueryMethods

dea*_*rma 204

如果要对一列的值使用OR运算符,可以将数组传递给.where,ActiveRecord将使用IN(value,other_value):

OR

输出:

Model.where(:column => ["value", "other_value"]
Run Code Online (Sandbox Code Playgroud)

这应该相当于.where单个列

  • 此解决方案不能替代OR,因为您不能以这种方式使用两个不同的列. (77认同)
  • 这是最干净最"铁路方式"的答案,本应该被接受 (13认同)
  • 谢谢@koonse,它不是*完全*'或'查询,但它会为这种情况产生相同的结果. (10认同)

rub*_*nce 149

在Rails 3中,它应该是

Model.where("column = ? or other_column = ?", value, other_value)
Run Code Online (Sandbox Code Playgroud)

这还包括原始sql但我不认为在ActiveRecord中有一种方法可以进行OR操作.你的问题不是一个菜鸟问题.

  • 即使有原始的sql - 这个语句对我来说比Arel更清晰.也许甚至DRYer. (38认同)
  • 如果你需要链接,其他表连接可能有相同列名的列,你应该像这样使用它,`Page.where("pages.column =?或pages.other_column =?",value,other_value)` (6认同)
  • 如果查询对表使用别名,则失败。这就是阿雷尔闪耀的时候。 (2认同)

Dan*_*vin 109

使用ARel

t = Post.arel_table

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

结果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%'))
Run Code Online (Sandbox Code Playgroud)

  • 我无法理解续集的优雅程度 (53认同)
  • SQL的另一个问题是它不是数据库不可知的.例如`matches`将为sqlite生成`LIKE`(默认情况下不区分大小写)和postgres上的`ILIKE`(需要像运算符一样的显式不区分大小写). (5认同)
  • SQL没有任何问题.可能出错的是我们如何构建SQL字符串,即[SQL Injection](http://en.wikipedia.org/wiki/SQL_injection).因此,在将用户输入提供给必须针对数据库运行的SQL查询之前,我们必须对其进行清理.这将由[ORM](http://en.wikipedia.org/wiki/Object-relational_mapping)处理,这些已经处理了我们往往会错过的边缘情况.因此,始终建议使用[ORM](http://en.wikipedia.org/wiki/Object-relational_mapping)来创建SQL查询. (3认同)
  • @ToniLeigh ActiveRecord 在底层使用 SQL。它只是编写 SQL 查询的语法,用于处理 SQL 清理并使您的查询与数据库无关。唯一的开销是 Rails 将语法转换为 SQL 查询的地方。而这只是几毫秒的问题。当然,您应该编写性能最佳的 SQL 查询并尝试将其转换为 ActiveRecord 语法。如果 SQL 无法用 ActiveRecord 语法表示,那么您应该使用纯 SQL。 (2认同)

Chr*_*ini 56

Rails/ActiveRecord的更新版本可以本机支持此语法.它看起来类似于:

Foo.where(foo: 'bar').or.where(bar: 'bar')
Run Code Online (Sandbox Code Playgroud)

如此拉动请求中所述https://github.com/rails/rails/pull/9052

现在,只需坚持下面的工作:

Foo.where('foo= ? OR bar= ?', 'bar', 'bar')
Run Code Online (Sandbox Code Playgroud)

更新:根据https://github.com/rails/rails/pull/16052,or功能将在Rails 5中提供

更新:功能已合并到Rails 5分支

  • `或`现在可用Rails 5但不是以这种方式实现的,因为它期望传递1个参数.它需要一个Arel对象.看到接受的答案 (2认同)
  • 如果直接使用ActiveRecord中的`或`方法,则可以使用:但是如果在随后链接的范围中使用它,可能会超出预期。 (2认同)

Gre*_*sen 34

Rails最近将其添加到ActiveRecord中.它似乎在Rails 5中发布.已经致力于掌握:

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)
Run Code Online (Sandbox Code Playgroud)


San*_*osh 19

Rails 5附带了一种or方法.(墨迹到文档)

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

User.where(first_name: 'James').or(User.where(last_name: 'Scott'))
Run Code Online (Sandbox Code Playgroud)


Raf*_*lak 14

如果要将数组用作参数,则以下代码适用于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))
Run Code Online (Sandbox Code Playgroud)

更多信息:在Rails 4中使用数组作为参数进行OR查询.

  • 或者:`Order.where(query.where_values.inject(:或))`一直使用arel. (9认同)

Duk*_*uke 7

MetaWhere插件完全是惊人的.

轻松混合OR和AND,在任何关联上加入条件,甚至指定OUTER JOIN!

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


Tob*_*ede 6

只需在条件中添加OR即可

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

  • 这是Rails 2的更多语法,它要求我至少写一部分sql字符串. (4认同)