Misalkan saya memiliki dua objek berikut:
first_name_relation = User.where(:first_name => 'Tobias') # ActiveRecord::Relation
last_name_relation = User.where(:last_name => 'Fünke') # ActiveRecord::Relation
Apakah mungkin untuk menggabungkan kedua relasi untuk menghasilkan satu ActiveRecord::Relation
objek yang mengandung kedua kondisi?
Catatan: Saya sadar bahwa saya bisa rantai di mana saja untuk mendapatkan perilaku ini, apa yang saya benar-benar tertarik adalah kasus di mana saya memiliki dua ActiveRecord::Relation
objek terpisah .
ruby-on-rails
rails-activerecord
arel
Patrick Klingemann
sumber
sumber
Jawaban:
Jika Anda ingin menggabungkan menggunakan
AND
(persimpangan), gunakanmerge
:Jika Anda ingin menggabungkan menggunakan
OR
(gabungan), gunakan † :or
† Hanya di ActiveRecord 5+; untuk 4.2, instal di mana-atau backport.
sumber
ActiveRecord::Relation
tipe?merge
adalah persimpangan, bukan penyatuan.#or
metode telah ditambahkan ke ActiveRecord :: Relation pada Jan 2015, dan itu akan menjadi bagian dari Rails 5.0 , yang akan dikirimkan pada akhir 2015. Ini memungkinkan penggunaan operator OR untuk menggabungkan klausa WHERE atau HAVING. Anda dapat checkout KEPALA jika Anda membutuhkannya sebelum rilis resmi. Lihat Permintaan Gabung Tarik # 16052 @Arcolye @AndrewMarshall @ Aldo-xoen-GiambellucaObjek relasi dapat dikonversi menjadi array. Ini meniadakan kemampuan untuk menggunakan metode ActiveRecord setelahnya, tetapi saya tidak perlu melakukannya. Saya melakukan ini:
Ruby 1.9, rails 3.2
sumber
merge
sebenarnya tidak bekerjaOR
. Ini hanya persimpangan (AND
)Saya kesulitan dengan masalah ini untuk menggabungkan ke objek ActiveRecord :: Relation menjadi satu dan saya tidak menemukan solusi yang berfungsi untuk saya.
Alih-alih mencari metode yang tepat membuat penyatuan dari dua set ini, saya fokus pada aljabar set. Anda dapat melakukannya dengan cara yang berbeda menggunakan hukum De Morgan
ActiveRecord menyediakan metode gabungan (DAN) dan Anda juga dapat menggunakan metode tidak atau none_dari (TIDAK).
Anda miliki di sini (A u B) '= A' ^ B '
UPDATE: Solusi di atas baik untuk kasus yang lebih kompleks. Dalam kasus Anda, pertanda seperti itu akan cukup:
sumber
Saya sudah bisa mencapai ini, bahkan dalam banyak situasi aneh, dengan menggunakan Arel bawaan Rails .
Ini menggabungkan kedua hubungan ActiveRecord dengan menggunakan Arel atau .
Penggabungan, seperti yang disarankan di sini, tidak berhasil untuk saya. Itu menjatuhkan set objek relasi ke-2 dari hasil.
sumber
Ada permata bernama active_record_union yang mungkin Anda cari.
Contoh penggunaannya adalah sebagai berikut:
sumber
ransack
danacts-as-taggable-on
menjagaActiveRecord
instans saya tetap utuh.Ini adalah cara saya "menanganinya" jika Anda menggunakan pluck untuk mendapatkan pengidentifikasi untuk masing-masing rekaman, bergabung dengan array bersama dan akhirnya melakukan kueri untuk id yang bergabung:
sumber
Jika Anda memiliki array hubungan activerecord dan ingin menggabungkan semuanya, Anda bisa melakukannya
sumber
array.inject(:merge)
tidak bekerja untuk array hubungan activerecord di rel 5.1.4. Tapi ituarray.flatten!
benar.Paksa itu:
sumber