web-dev-qa-db-fra.com

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

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

Donne 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?

95
BoosterStage

L'option uniq doit être déplacée dans un bloc de portée. 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 le :through => :donations partie):

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
236
Dylan Markow

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 (par opposition à le spécifier séparément), comme ceci:

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

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

5
Andrew Hacking