Avertissement de dépréciation lors de l'utilisation de has_many: through: uniq dans Rails 4


95

Rails 4 a introduit un avertissement de dépréciation lors de l'utilisation de: uniq => true avec has_many: through. Par exemple:

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

Renvoie l'avertissement suivant:

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'

Quelle est la bonne façon de réécrire la déclaration has_many ci-dessus?

Réponses:


237

L' uniqoption doit être déplacée dans un bloc d'étendue. Notez que le bloc de portée doit être le deuxième paramètre de has_many(c'est- à -dire que vous ne pouvez pas le laisser à la fin de la ligne, il doit être déplacé avant la :through => :donationspièce):

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

Cela peut sembler étrange, mais cela a un peu plus de sens si vous considérez le cas où vous avez plusieurs paramètres. Par exemple, ceci:

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

devient:

has_many :donors, -> { where("age < 30").order("name").uniq }, :through => :donations

Merci, cela fonctionne très bien! Où as tu trouvé ça? Je n'ai pu le trouver nulle part dans la documentation.
Ryan Crispin Heneise

6
Je l'ai vu dans le livre Upgrading to Rails 4 (il est en cours): upgradeingtorails4.com - je n'ai pu le trouver nulle part ailleurs.
Dylan Markow

1
@DylanMarkow le lien pour la mise à niveau vers Rails 4 est obsolète. Le livre est maintenant publié sous une licence CC sur github.com/alindeman/upgradingtorails4
Ivar

1
Avec Rails 5, utilisez à la distinctplace de uniq. Voir cette réponse pour plus de détails.
Nic Nilov

5

En plus de la réponse de Dylans, si vous étendez l'association avec un module, assurez-vous de l'enchaîner dans le bloc de portée (au lieu de le spécifier séparément), comme ceci:

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

Peut-être que c'est juste moi, mais il semble très peu intuitif d'utiliser un bloc de portée pour étendre un proxy d'association.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.