Saya bertanya-tanya apa cara terbaik untuk menampilkan catatan unik dari has_many, melalui hubungan di Rails3.
Saya punya tiga model:
class User < ActiveRecord::Base
has_many :orders
has_many :products, :through => :orders
end
class Products < ActiveRecord::Base
has_many :orders
has_many :users, :through => :orders
end
class Order < ActiveRecord::Base
belongs_to :user, :counter_cache => true
belongs_to :product, :counter_cache => true
end
Katakanlah saya ingin mencantumkan semua produk yang dipesan pelanggan di halaman pertunjukan mereka.
Mereka mungkin telah memesan beberapa produk beberapa kali, jadi saya menggunakan counter_cache untuk menampilkan dalam urutan peringkat menurun, berdasarkan jumlah pesanan.
Tapi, jika mereka sudah memesan produk beberapa kali, saya perlu memastikan bahwa setiap produk hanya terdaftar satu kali.
@products = @user.products.ranked(:limit => 10).uniq!
berfungsi ketika ada beberapa catatan pesanan untuk suatu produk, tetapi menghasilkan kesalahan jika produk hanya dipesan sekali. (peringkat adalah fungsi pengurutan khusus yang ditentukan di tempat lain)
Alternatif lainnya adalah:
@products = @user.products.ranked(:limit => 10, :select => "DISTINCT(ID)")
Saya tidak yakin bahwa saya menggunakan pendekatan yang benar di sini.
Apakah ada orang lain yang menangani ini? Masalah apa yang Anda hadapi? Di mana saya dapat mengetahui lebih lanjut tentang perbedaan antara .unique! dan DISTINCT ()?
Apa cara terbaik untuk menghasilkan daftar catatan unik melalui has_many, through relationship?
Terima kasih
sumber
has_many :products, :through => :orders, :uniq => true
sudah tidak digunakan lagi. Sebaliknya, Anda sekarang harus menulishas_many :products, -> { uniq }, through: :orders
.DISTINCT
danORDER BY
, Anda selalu dapat menggunakanhas_many :products, -> { unscope(:order).distinct }, through: :orders
has_many :subscribed_locations, -> { unscope(:order).select("DISTINCT ON (locations.id) locations.*") },through: :people_publication_subscription_locations, class_name: 'Location', source: :location
jika tidakrails ActiveRecord::StatementInvalid: PG::UndefinedFunction: ERROR: could not identify an equality operator for type json
Perhatikan bahwa
uniq: true
telah dihapus dari opsi yang valid untukhas_many
per Rails 4.Di Rails 4 Anda harus menyediakan ruang lingkup untuk mengkonfigurasi perilaku semacam ini. Cakupan dapat dipasok melalui lambda, seperti:
Panduan rails mencakup ini dan cara lain Anda dapat menggunakan cakupan untuk memfilter kueri relasi Anda, gulir ke bawah ke bagian 4.3.3:
http://guides.rubyonrails.org/association_basics.html#has-many-association-reference
sumber
undefined method 'except' for #<Array...
dan itu karena saya menggunakan.uniq
bukannya.distinct
Anda bisa menggunakan
group_by
. Misalnya, saya memiliki keranjang belanja galeri foto yang saya ingin item pesanannya diurutkan berdasarkan foto mana (setiap foto dapat dipesan beberapa kali dan dalam ukuran cetakan yang berbeda). Ini kemudian mengembalikan hash dengan produk (foto) sebagai kuncinya dan setiap kali dipesan dapat dicantumkan dalam konteks foto (atau tidak). Dengan menggunakan teknik ini, Anda sebenarnya dapat mengeluarkan riwayat pesanan untuk setiap produk tertentu. Tidak yakin apakah itu membantu Anda dalam konteks ini, tetapi menurut saya itu cukup berguna. Ini kodenya@order_items_by_photo
kemudian terlihat seperti ini:Jadi Anda bisa melakukan sesuatu seperti:
Kemudian saat Anda mendapatkan ini dalam tampilan Anda, cukup putar melalui sesuatu seperti ini:
Dengan cara ini Anda menghindari masalah yang terlihat saat mengembalikan hanya satu produk, karena Anda selalu tahu bahwa itu akan mengembalikan hash dengan produk sebagai kunci dan larik pesanan Anda.
Mungkin berlebihan untuk apa yang Anda coba lakukan, tetapi itu memberi Anda beberapa pilihan bagus (misalnya tanggal dipesan, dll.) Untuk dikerjakan selain kuantitas.
sumber
Di Rails 6 saya membuat ini bekerja dengan sempurna:
Saya tidak bisa mendapatkan jawaban lain untuk bekerja.
sumber