Bagaimana Anda melakukan orkueri di Rails 5 ActiveRecord? Juga, apakah mungkin untuk terhubung ordengan wherekueri ActiveRecord?
Bagaimana Anda melakukan orkueri di Rails 5 ActiveRecord? Juga, apakah mungkin untuk terhubung ordengan wherekueri ActiveRecord?
Jawaban:
Kemampuan untuk merangkai orklausa bersama dengan whereklausa dalam ActiveRecordkueri akan tersedia di Rails 5 . Lihat diskusi terkait dan permintaan tarik .
Jadi, Anda akan dapat melakukan hal-hal berikut di Rails 5 :
Untuk mendapatkan postdengan id1 atau 2:
Post.where('id = 1').or(Post.where('id = 2'))
Beberapa contoh lain:
(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)))ini harus membuat (a || b) && (c || d)
ArgumentError: Unsupported argument type: #<MyModel::ActiveRecord_Relation:0x00007f8edbc075a8> (MyModel::ActiveRecord_Relation)
Saya perlu melakukan a (A && B) || (C && D) || (E && F)
Tapi dalam kondisi Rails 5.1.4saat ini, hal ini terlalu rumit untuk diselesaikan dengan Arel atau rantai. Tapi saya masih ingin menggunakan Rails untuk menghasilkan kueri sebanyak mungkin.
Jadi saya membuat retasan kecil:
Dalam model saya, saya membuat metode pribadi yang disebut sql_where:
private
def self.sql_where(*args)
sql = self.unscoped.where(*args).to_sql
match = sql.match(/WHERE\s(.*)$/)
"(#{match[1]})"
end
Selanjutnya dalam ruang lingkup saya, saya membuat sebuah array untuk menampung 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 '))
}
Yang akan menghasilkan hasil query yang diharapkan:
SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F)).
Dan sekarang saya dapat dengan mudah menggabungkan ini dengan cakupan lain, dll. Tanpa OR yang salah.
Keindahannya adalah bahwa sql_where saya mengambil argumen klausa where-clause yang normal:
sql_where(name: 'John', role: 'admin')akan menghasilkan (name = 'John' AND role = 'admin').
.mergesebagai padanan &&, dan membangun pohon yang tepat untuk menangkap orang tua Anda. Sesuatu seperti ... (scopeA.merge(scopeB)).or(scopeC.merge(scopeD)).or(scopeE.merge(scopeF)), dengan asumsi masing-masing cakupan terlihat sepertiModel.where(...)
Rails 5 memiliki kemampuan untuk orklausa dengan where. Sebagai contoh.
User.where(name: "abc").or(User.where(name: "abcd"))