Rails 5 ActiveRecordでor
クエリをどのように行いますか?また、ActiveRecordクエリでor
をwhere
と連鎖させることは可能ですか?
or
句とwhere
句をActiveRecord
クエリで連結する機能は、Rails 5。 関連する議論とプルリクエスト をご覧ください。
そのため、Rails 5で次のことを実行できます。
post
1または2でid
を取得するには
Post.where('id = 1').or(Post.where('id = 2'))
他の例:
(A && B)|| C:
Post.where(a).where(b).or(Post.where(c))
(A || B)&& C:
Post.where(a).or(Post.where(b)).where(c)
(K M Rakibul Islamの答えに加えて)
スコープを使用すると、コードがきれいになります(見ている目によって異なります)。
scope a, -> { where(a) }
scope b, -> { where(b) }
scope a_or_b, -> { a.or(b) }
(A && B) || (C && D) || (E && F)
を行う必要がありました
しかし、Rails 5.1.4
の現在の状態では、これはArelまたはチェーンで達成するには複雑すぎます。しかし、Railsを使用して、可能な限り多くのクエリを生成したかったのです。
だから私は小さなハックを作りました:
私のモデルでは、sql_where
というprivateメソッドを作成しました。
private
def self.sql_where(*args)
sql = self.unscoped.where(*args).to_sql
match = sql.match(/WHERE\s(.*)$/)
"(#{match[1]})"
end
次に、スコープ内でORを保持する配列を作成しました
scope :whatever, -> {
ors = []
ors << sql_where(A, B)
ors << sql_where(C, D)
ors << sql_where(E, F)
# Now just combine the stumps:
where(ors.join(' OR '))
}
予想されるクエリ結果が生成されます:SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F))
。
そして今、私はこれを他のスコープと簡単に組み合わせることができます。
私のsql_whereが通常のwhere-clause引数を取ることの美しさ:sql_where(name: 'John', role: 'admin')
は(name = 'John' AND role = 'admin')
を生成します。
Rails 5には、or
を含むwhere
句の機能があります。例えば。
User.where(name: "abc").or(User.where(name: "abcd"))