Verfallswarnung bei Verwendung von has_many: through: uniq in Rails 4

95

Rails 4 hat eine Verfallswarnung eingeführt, wenn Folgendes verwendet wird: uniq => true mit has_many: through. Beispielsweise:

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

Gibt folgende Warnung aus:

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'

Was ist der richtige Weg, um die obige has_many-Deklaration neu zu schreiben?

Ryan Crispin Heneise
quelle

Antworten:

237

Die uniqOption muss in einen Bereichsblock verschoben werden. Beachten Sie, dass der Bereichsblock der zweite Parameter sein muss has_many(dh Sie können ihn nicht am Ende der Zeile belassen, er muss vor dem :through => :donationsTeil verschoben werden ):

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

Es mag seltsam aussehen, aber es ist etwas sinnvoller, wenn Sie den Fall betrachten, in dem Sie mehrere Parameter haben. Zum Beispiel:

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

wird:

has_many :donors, -> { where("age < 30").order("name").uniq }, :through => :donations
Dylan Markow
quelle
Danke, das funktioniert super! Wo hast du das gefunden? Ich konnte es nirgendwo in der Dokumentation finden.
Ryan Crispin Heneise
6
Ich habe es tatsächlich im Buch Upgrade auf Rails 4 gesehen (es ist in Bearbeitung): upgradeingtorails4.com - konnte es nirgendwo anders finden.
Dylan Markow
1
@DylanMarkow Der Link für das Upgrade auf Rails 4 ist nicht mehr vorhanden. Das Buch wurde jetzt unter einer CC-Lizenz unter github.com/alindeman/upgradingtorails4
Ivar
1
Mit Rails 5 distinctanstelle von verwenden uniq. Siehe diese Antwort für weitere Details.
Nic
5

Wenn Sie die Zuordnung zu einem Modul erweitern, stellen Sie zusätzlich zur Antwort von Dylans sicher, dass Sie sie im Bereichsblock verketten (anstatt sie separat anzugeben).

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

Vielleicht bin ich es nur, aber es scheint sehr unintuitiv zu sein, einen Bereichsblock zu verwenden, um einen Assoziations-Proxy zu erweitern.

Andrew Hacking
quelle