que he tenido este modelo, que estaba trabajando bien:validates_presence_of causa after_initialize para ser llamado con un auto extraño
class Weight < ActiveRecord::Base
belongs_to :user
validates_presence_of :weight, :measured_on
attr_accessible :weight, :measured_on
def after_initialize
self.measured_on ||= Date.today
end
end
he añadido esta línea
validates_uniqueness_of :measured_on, :scope => :user_id
y comenzaron a arrojar un error en validación. No es un error de validación, pero un error de Ruby:
>> w.valid?
ActiveRecord::MissingAttributeError: missing attribute: measured_on
from /Users/pupeno/Projects/sano/app/models/weight.rb:8:in `after_initialize'
He puesto una declaración depurador en after_initialize y me he dado cuenta de algo inesperado. Cuando creo un nuevo peso funciona como se esperaba y el objeto mismo en after_initialize es el peso esperado:
>> w = Weight.new
/Users/pupeno/Projects/sano/app/models/weight.rb:9
self.measured_on ||= Date.today
(rdb:1) p self
#<Weight id: nil, user_id: nil, weight: nil, measured_on: nil, created_at: nil, updated_at: nil>
(rdb:1) c
=> #<Weight id: nil, user_id: nil, weight: nil, measured_on: "2009-11-22", created_at: nil, updated_at: nil>
Cuando corro w.valid? se pone raro after_initialize se llama de nuevo, no estoy seguro de por qué, y el objeto mismo es nada de lo que esperaba:
>> w.valid?
/Users/pupeno/Projects/sano/app/models/weight.rb:9
self.measured_on ||= Date.today
(rdb:1) p self
#<Weight id: 1>
(rdb:1) p self.inspect
"#<Weight id: 1>"
(rdb:1) p self.class
Weight(id: integer, user_id: integer, weight: float, measured_on: date, created_at: datetime, updated_at: datetime)
(rdb:1) p self.measured_on
ActiveRecord::MissingAttributeError Exception: missing attribute: measured_on
(rdb:1)
Parece que otro objeto de peso fue creada sin ningún atributo pero el conjunto de Identificación. ¿Alguna idea de por qué? ¿Es esto un error o el comportamiento esperado? ¿Estoy haciendo algo mal al configurar el medido encendido after_initialize?
Mi solución actual, en caso de que alguien está teniendo el mismo problema, es
class Weight < ActiveRecord::Base
belongs_to :user
validates_presence_of :weight, :measured_on
validates_uniqueness_of :measured_on, :scope => :user_id
attr_accessible :weight, :measured_on
def after_initialize
if self.has_attribute? :measured_on
self.measured_on ||= Date.today
end
end
end
pero me gustaría tener una solución adecuada.
El OP editó mi respuesta y creó la sección "has_attribute?: Measured_on" - No estoy 100% seguro de estar de acuerdo con ella después de mirar la fuente de los rieles - Sospecho que funciona debido a un efecto secundario, en lugar de por -diseño). Sin embargo, no estoy retrasando esa parte de la respuesta, ya que, quién sabe, puede ayudar a alguien. – oskarpearson
Hoy me han mordido esto. Esta publicación y tu respuesta salvó mi tocino. Había olvidado que una de las desventajas de los lenguajes dinámicos es que no siempre tienes los mismos atributos en un objeto ... lo que podría ser bueno, pero también malo :) –
Hoy lo he mordido. Wow, esto fue publicado aquí en 2009? Estoy impresionado de que no se haya corregido durante tanto tiempo. – Trejkaz