Anular el acceso de atributos del modelo en un mixin/módulo

Tengo un modelo que incluye un módulo. Me gustaría anular los métodos de acceso del modelo dentro del módulo.

Por ejemplo:

class Blah < ActiveRecord::Base
  include GnarlyFeatures
  # database field: name
end

module GnarlyFeatures
  def name=(value)
    write_attribute :name, "Your New Name"
  end
end

Esto obviamente no funciona. ¿Alguna idea para lograr esto?

preguntado el 03 de mayo de 12 a las 18:05

1 Respuestas

Su código parece correcto. Estamos usando este patrón exacto sin ningún problema.

Si no recuerdo mal, Rails usa #method_missing para los setters de atributos, por lo que su módulo tendrá prioridad, bloqueando el setter de ActiveRecord.

Si está utilizando ActiveSupport::Concern (ver esta entrada del blog, entonces sus métodos de instancia deben ir a un módulo especial:

class Blah < ActiveRecord::Base
  include GnarlyFeatures
  # database field: name
end

module GnarlyFeatures
  extend ActiveSupport::Concern

  included do
    def name=(value)
      write_attribute :name, value
    end
  end
end

Respondido el 02 de enero de 13 a las 21:01

Hmmmm. Debo estar haciendo algo mal. ¿Qué tal si amplía ActiveSuppport::Concern como parte del módulo? - KendallB

¡Impresionante! Eso ayudó. Sin embargo, no era exacto. En Rails 3.2, parece que InstanceMethods ya no está incluido: la advertencia de desaprobación simplemente decía que se incluyera el acceso en el bloque "incluido". - KendallB

Por supuesto. ActiveSupport::Concern ha pasado por algunos cambios. - tihm

¿Cuál es el punto del valor arg en el método def name=? Tal vez eso debería usarse en lugar de "Tu nuevo nombre" - justingordon

ActiveSupport::Concern en Rails 4 necesita que definas def self.included en vez de included do bloquear. api.rubyonrails.org/classes/ActiveSupport/Concern.html - Abdo

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.