ActiveRecord OR查询

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

编辑:方法自Rails 5起可用。看到ActiveRecord:: QueryMethods

158518 次浏览

只要在条件中添加一个OR

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

使用服装

t = Post.arel_table


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

结果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%'))

MetaWhere插件是完全惊人的。

轻松混合OR's和and 's,任何关联的连接条件,甚至指定OUTER join 's!

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

在Rails 3中,应该是这样

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

这也包括原始sql,但我不认为有一种方式在ActiveRecord做或操作。你的问题不是新手的问题。

Rails 5添加了,所以现在在Rails版本大于5的应用程序中更容易做到这一点:

Model.where(column: value).or(Model.where(other_column: other_value)

它也处理nil

我刚刚从客户端工作中提取了这个插件,允许你将作用域与.or.结合,例如Post.published.or.authored_by(current_user)。Squeel (MetaSearch的更新实现)也很棒,但不支持OR作用域,因此查询逻辑可能有点多余。

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

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

输出:

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

这应该相当于在单个列上使用OR

如果你想使用数组作为参数,下面的代码在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))

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

Rails/ActiveRecord的更新版本可能原生支持此语法。它看起来类似于:

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

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

现在,只要坚持下面的方法就可以了:

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

根据https://github.com/rails/rails/pull/16052or特性将在Rails 5中可用

更新:特性已合并到Rails 5分支

rails + arel,一个更清晰的方式:

# 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

生产:

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

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)

使用activerecord_any_of宝石,你可以写

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

Rails 5附带了一个or方法。(l文件油墨)

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

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

你可以这样做:

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

或者更优雅,安装rails_or gem,并像这样做:

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

我想添加这是一个解决方案搜索一个ActiveRecord的多个属性。自

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

会搜索A和B。