Rails 5 ActiveRecordでor
クエリを実行するにはどうすればよいですか?また、ActiveRecordクエリでチェーンすることは可能ですか?or
where
Rails 5 ActiveRecordでor
クエリを実行するにはどうすればよいですか?また、ActiveRecordクエリでチェーンすることは可能ですか?or
where
回答:
クエリor
でwhere
句と一緒に句をチェーンする機能ActiveRecord
は、Rails 5で利用できるようになります。参照関連する議論とプル要求を。
したがって、Rails 5では次のことができるようになります。
1または2 post
でを取得するには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)
Post.where(a).or(Post.where(b)).where(Post.where(c).or(Post.where(d)))
(a || b)&&(c || d)を作成するべきだと思います
ArgumentError: Unsupported argument type: #<MyModel::ActiveRecord_Relation:0x00007f8edbc075a8> (MyModel::ActiveRecord_Relation)
私はする必要がありました (A && B) || (C && D) || (E && F)
しかし、Rails 5.1.4
の現在の状態では、これは複雑すぎてArelまたはチェーンで実行できません。しかし、私はまだRailsを使用してできるだけ多くのクエリを生成したいと思っていました。
だから私は小さなハックを作りました:
私のモデルでは、次の名前のプライベートメソッドを作成しましたsql_where
。
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句の引数をとるという美しさは、
sql_where(name: 'John', role: 'admin')
を生成し(name = 'John' AND role = 'admin')
ます。
.merge
&&の同等物として使用して、括弧をキャプチャする適切なツリーを構築できると思います。...のような何か(scopeA.merge(scopeB)).or(scopeC.merge(scopeD)).or(scopeE.merge(scopeF))
スコープのそれぞれを想定しては、のようなものに見えるModel.where(...)