Rails 3のActiveRecordでORクエリを行う方法を教えてください。私が見つけたすべての例には、ANDクエリしかありません。
編集:ORメソッドはRails 5以降で使用できます。ActiveRecord:: QueryMethodsを参照してください
Post.where(column: 'something').or(Post.where(other: 'else'))
Rails 3のActiveRecordでORクエリを行う方法を教えてください。私が見つけたすべての例には、ANDクエリしかありません。
編集:ORメソッドはRails 5以降で使用できます。ActiveRecord:: QueryMethodsを参照してください
Post.where(column: 'something').or(Post.where(other: 'else'))
回答:
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%'))
matches
生成されますLIKE
sqliteの(デフォルトではケースの小文字を区別しない)のためにとILIKE
postgresの上(オペレータのような明示的なケース小文字を区別しないが必要です)。
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
により、1つの列と同等の
Rails 3では、それは
Model.where("column = ? or other_column = ?", value, other_value)
これには未加工のSQLも含まれますが、ActiveRecordにOR操作を行う方法があるとは思いません。あなたの質問はnoobの質問ではありません。
Page.where("pages.column = ? or pages.other_column = ?", value, other_value)
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ブランチにマージされました
or
は現在Rails 5で利用できますが、1つの引数が渡されることを想定しているため、この方法では実装されません。Arelオブジェクトが必要です。承認された回答を見る
or
ActiveRecord のメソッドは、直接使用している場合は機能しますが、スコープ内で使用すると、期待どおりに動作しない可能性があります。
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)
Rails 5にはor
メソッドが付属しています。(ドキュメンテーションへのインク)
このメソッドはActiveRecord::Relation
オブジェクトを受け入れます。例えば:
User.where(first_name: 'James').or(User.where(last_name: 'Scott'))
配列を引数として使用する場合、次のコードは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))
Order.where(query.where_values.inject(:or))
arelをずっと使うため。
条件にORを追加するだけです
Model.find(:all, :conditions => ["column = ? OR other_column = ?",value, other_value])
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
Book.where.any_of(Book.where(:author => 'Poe'), Book.where(:author => 'Hemingway')