Advertencia de obsolescencia al usar has_many: through: uniq en Rails 4


95

Rails 4 ha introducido una advertencia de obsolescencia al usar: uniq => true con has_many: through. Por ejemplo:

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

Produce la siguiente advertencia:

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'

¿Cuál es la forma correcta de reescribir la declaración has_many anterior?

Respuestas:


237

La uniqopción debe moverse a un bloque de alcance. Tenga en cuenta que el bloque de alcance debe ser el segundo parámetro has_many(es decir, no puede dejarlo al final de la línea, debe moverse antes de la :through => :donationsparte):

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

Puede parecer extraño, pero tiene un poco más de sentido si considera el caso en el que tiene varios parámetros. Por ejemplo, esto:

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

se convierte en:

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

Gracias, esto funciona muy bien. ¿Dónde encontraste esto? No he podido encontrarlo en la documentación en ninguna parte.
Ryan Crispin Heneise

6
De hecho, lo vi en el libro Upgrading to Rails 4 (está en progreso): upgradingtorails4.com - no he podido encontrarlo en ningún otro lugar.
Dylan Markow

1
@DylanMarkow, el enlace para actualizar a Rails 4 está inactivo. El libro ahora se ha publicado bajo una licencia CC en github.com/alindeman/upgradingtorails4
Ivar

1
Con Rails 5 use en distinctlugar de uniq. Consulte esta respuesta para obtener más detalles.
Nic Nilov

5

Además de la respuesta de Dylans, si está extendiendo la asociación con un módulo, asegúrese de encadenarlo en el bloque de alcance (en lugar de especificarlo por separado), así:

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

Tal vez sea solo yo, pero parece muy poco intuitivo usar un bloque de alcance para extender un proxy de asociación.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.