Peringatan penghentian saat menggunakan has_many: through: uniq di Rails 4

95

Rails 4 telah memperkenalkan peringatan penghentian saat menggunakan: uniq => true dengan has_many: through. Sebagai contoh:

has_many :donors, :through => :donations, :uniq => true

Menghasilkan peringatan berikut:

DEPRECATION WARNING: The following options in your Goal.has_many :donors declaration are deprecated: :uniq. Please use a scope block instead. For example, the following:

    has_many :spam_comments, conditions: { spam: true }, class_name: 'Comment'

should be rewritten as the following:

    has_many :spam_comments, -> { where spam: true }, class_name: 'Comment'

Apa cara yang benar untuk menulis ulang deklarasi has_many di atas?

Ryan Crispin Heneise
sumber

Jawaban:

237

The uniqpilihan harus dipindahkan ke blok lingkup. Perhatikan bahwa blok ruang lingkup harus menjadi parameter kedua has_many(yaitu Anda tidak dapat meninggalkannya di akhir baris, itu perlu dipindahkan sebelum :through => :donationsbagian):

has_many :donors, -> { uniq }, :through => :donations

Ini mungkin terlihat aneh, tetapi akan lebih masuk akal jika Anda mempertimbangkan kasus di mana Anda memiliki beberapa parameter. Misalnya, ini:

has_many :donors, :through => :donations, :uniq => true, :order => "name", :conditions => "age < 30"

menjadi:

has_many :donors, -> { where("age < 30").order("name").uniq }, :through => :donations
Dylan Markow
sumber
Terima kasih, ini berfungsi dengan baik! Di mana kamu menemukan ini? Saya belum bisa menemukannya di dokumentasi mana pun.
Ryan Crispin Heneise
6
Saya benar-benar melihatnya di buku Upgrading to Rails 4 (sedang dalam proses): upgradingtorails4.com - belum dapat menemukannya di tempat lain.
Dylan Markow
1
@DylanMarkow link untuk Mengupgrade ke Rails 4 sudah tidak berfungsi. Buku ini sekarang telah dirilis di bawah lisensi CC di github.com/alindeman/upgradingtorails4
Ivar
1
Dengan Rails 5 digunakan distinctsebagai pengganti uniq. Lihat jawaban ini untuk lebih jelasnya.
Nic Nilov
5

Selain jawaban Dylans, jika Anda kebetulan memperluas pengaitan dengan modul, pastikan Anda merantai itu di blok cakupan (bukan menentukannya secara terpisah), seperti:

has_many :donors,
  -> { extending(DonorExtensions).order(:name).uniq },
  through: :donations

Mungkin hanya saya, tetapi tampaknya sangat tidak intuitif menggunakan blok lingkup untuk memperluas proxy asosiasi.

Andrew Hacking
sumber