¿Cómo puedo sobrescribir un método getter en un modelo ActiveRecord?


98

Estoy tratando de sobrescribir un método getter para un modelo ActiveRecord. Tengo un atributo llamado nameen el modelo Categoryy me gustaría poder hacer algo como esto:

def name
  name_trans || name
end

Si el name_transatributo no es nulo, devuélvalo; de lo contrario, devuelva el nameatributo. ¿Cómo haría esto?

Esto debería llamarse normalmente así:

@category.name

Respuestas:



98

Actualización: el método preferido de acuerdo con la Guía de estilo de Rails es usar en self[:name]lugar de read_attributey write_attribute. Te animo a que omitas mi respuesta y prefieras esta .


Puede hacerlo exactamente así, excepto que debe usarlo read_attributepara recuperar el valor del atributo de nombre y evitar la llamada recursiva al namemétodo:

def name 
  name_trans || read_attribute(:name)
end

2
Cualquier idea de por qué Rubocop prefiere self[:name]más read_attribute[:name]?
Zack Xu

18

Me gustaría agregar otra opción para sobrescribir el método getter, que es simplemente: super.

def name
  name_trans || super
end

esto no solo funciona en el método getter de atributos, sino también en los métodos getter de asociaciones, también。


1
Esto es lo que recomiendan actualmente las guías de Rails, para captadores Y definidores
sandre89

5

Anular el getter y usar read_attributeno funciona para asociaciones, pero puede usar alias_method_chainen su lugar.

def name_with_override
  name_trans || name_without_override
end

alias_method_chain :name, :override

¿Puede dar un ejemplo adecuado ...?
Arup Rakshit

Bien. Acabo de ver el doco . Ahora, si invoco nameel objeto modelo, ¿cuál se llamará name_with_overrideo name_without_override?
Arup Rakshit

1
nameahora llamará name_with_override. Si desea llamar al método original por alguna razón, puede llamar name_without_override.
Patrick Oscity

Ya veo ... Gracias por sus respuestas //
Arup Rakshit

2

Si usa atributos de tienda como este

store :settings, accessors: [:volume_adjustment] 

o usando gemas como hstore_accessor enlace de gemas

Así que terminó usando el storemétodo en el modelo, luego, para anular esos métodos que no puede usar self.read_attribute, debe usar en su lugar superasí:

def partner_percentage
  super.to_i || 10
end

0

Si alguien quiere actualizar el valor después del name_transmétodo getter, puede usar self [: name] =.

def name
  self[:name] = name_trans || self[:name]
  # don't do this, it will cause endless loop
  # update(name: name_trans)
end

0

Puede utilizar el método read_attribute de Rails. Documentos de rieles


Si bien este enlace puede responder la pregunta, las respuestas de solo enlace no están permitidas en SO, agregue algo de contexto a su respuesta de lo que hay detrás de ese enlace. ¡Gracias! :)
AJT82
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.