rails new mvc create belong association and active ruby-on-rails-3 activerecord activemodel

ruby on rails 3 - new - Pista sucia para atributos no persistentes en un objeto ActiveRecord en rieles



ruby on rails mvc (3)

Descubrí una solución que funcionó para mí ...

Guarde este archivo como lib/active_record/nonpersisted_attribute_methods.rb : https://gist.github.com/4600209

Entonces puedes hacer algo como esto:

require ''active_record/nonpersisted_attribute_methods'' class Foo < ActiveRecord::Base include ActiveRecord::NonPersistedAttributeMethods define_nonpersisted_attribute_methods [:bar] end foo = Foo.new foo.bar = 3 foo.bar_changed? # => true foo.bar_was # => nil foo.bar_change # => [nil, 3] foo.changes[:bar] # => [nil, 3]

Sin embargo, parece que recibimos una advertencia cuando lo hacemos de esta manera:

DEPRECATION WARNING: You''re trying to create an attribute `bar''. Writing arbitrary attributes on a model is deprecated. Please just use `attr_writer` etc.

Así que no sé si este enfoque se romperá o será más difícil en Rails 4 ...

Tengo un objeto que se hereda de ActiveRecord, pero tiene un atributo que no se conserva en la base de datos, como:

class Foo < ActiveRecord::Base attr_accessor :bar end

Me gustaría poder realizar un seguimiento de los cambios en ''bar'', con métodos como ''bar_changed?'', Según lo provisto por ActiveModel Dirty. El problema es que cuando intento implementar Dirty en este objeto, como se describe en los docs , define_attribute_methods un error, ya que tanto ActiveRecord como ActiveModel han definido define_attribute_methods , pero con un número diferente de parámetros, por lo que recibo un error cuando tratando de invocar define_attribute_methods [:bar] .

He intentado define_attribute_methods alias define_attribute_methods antes de incluir ActiveModel::Dirty , pero sin suerte: define_attribute_methods un error de método no definido.

¿Alguna idea sobre cómo lidiar con esto? Por supuesto, podría escribir los métodos requeridos manualmente, pero me preguntaba si sería posible utilizar los módulos Rails, extendiendo la funcionalidad de ActiveModel a los atributos que no controla ActiveRecord.


Escriba la barra = método usted mismo y use una variable de instancia para rastrear los cambios.

def bar=(value) @bar_changed = true @bar = value end def bar_changed? if @bar_changed @bar_changed = false return true else return false end end


Estoy usando el attribute_will_change! Método y las cosas parecen estar funcionando bien.

Es un método privado definido en active_model/dirty.rb , pero ActiveRecord lo mezcla en todos los modelos.

Esto es lo que terminé implementando en mi clase modelo:

def bar @bar ||= init_bar end def bar=(value) attribute_will_change!(''bar'') if bar != value @bar = value end def bar_changed? changed.include?(''bar'') end

El método init_bar solo se utiliza para inicializar el atributo. Puede o no puede necesitarlo.

No tuve que especificar ningún otro método (como define_attribute_methods ) ni incluir ningún módulo. Tiene que volver a implementar algunos de los métodos usted mismo, pero al menos el comportamiento será mayormente consistente con ActiveModel.

Admito que todavía no lo he probado a fondo, pero hasta ahora no he encontrado ningún problema.