web-dev-qa-db-ja.com

ActiveRecord ORクエリ

OR 3 ActiveRecordでRailsクエリを実行するにはどうすればよいですか。私が見つけるすべての例には、ANDクエリがあります。

編集:またはメソッドはRails 5.以降使用可能です。 ActiveRecord :: QueryMethods を参照してください

173
pho3nixf1re

ARel を使用

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%'))
108
Dan McNevin

1つの列の値に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と同等の結果が得られます。

198
deadkarma

Rails 3では、

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

これには生のSQLも含まれますが、ActiveRecordでOR操作を行う方法はないと思います。あなたの質問は、noobの質問ではありません。

147
rubyprince

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/16052 により、or機能が利用可能になりますRails 5

更新:機能がRails 5ブランチにマージされました

55

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)
34
Greg Olsen

Rails 5にはorメソッドが付属しています。 (l ドキュメントへのインク

このメソッドはActiveRecord::Relationオブジェクトを受け入れます。例えば:

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

引数として配列を使用する場合、次のコードは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))

詳細: OR Rails 4の引数として配列を使用したクエリ

14
Rafał Cieślak

MetaWhere プラグインは完全に素晴らしいです。

ORとANDを簡単に組み合わせ、任意の関連付けの条件に参加し、さらに外部結合を指定することもできます!

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

条件にORを追加するだけです

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

私は このプラグイン を抽出しました。これにより、スコープを.or.と組み合わせることができます。 Post.published.or.authored_by(current_user)。 Squeel(MetaSearchの新しい実装)も優れていますが、ORスコープを許可しないため、クエリロジックが少し冗長になる可能性があります。

3
Woahdae

次のようにできます:

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

よりエレガントに、 Rails_or gemをインストールして次のようにします:

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

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
2
itsnikolay