Ho avuto questo modello che stava lavorando bene:validates_presence_of provoca after_initialize di essere chiamato con un auto strano
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
ho aggiunto questa linea
validates_uniqueness_of :measured_on, :scope => :user_id
ed è iniziato a gettare un errore convalida. Non è un errore di convalida, ma un errore di Rubino:
>> w.valid?
ActiveRecord::MissingAttributeError: missing attribute: measured_on
from /Users/pupeno/Projects/sano/app/models/weight.rb:8:in `after_initialize'
ho messo una dichiarazione debugger in after_initialize e ho notato qualcosa di inaspettato. Quando creo un nuovo peso funziona come previsto e l'oggetto sé sul after_initialize è il peso previsto:
>> 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>
Quando eseguo w.valid? diventa strano after_initialize è chiamato ancora una volta, io non so perché, e l'oggetto sé è niente che mi aspettavo:
>> 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)
Sembra che un altro oggetto peso è stato creato senza alcun attributo ma il set id. Tutte le idee perché? È un bug o il comportamento previsto? Sto facendo qualcosa di sbagliato impostando measur_on su after_initialize?
mia soluzione corrente, nel caso in cui qualcuno sta avendo lo stesso problema, è
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
ma mi piacerebbe avere una soluzione adeguata.
L'OP ha modificato la mia risposta e creato la sezione "has_attribute?: Measured_on" - Non sono sicuro al 100% che sia d'accordo con esso dopo aver esaminato la fonte dei binari - sospetto che funzioni a causa di un effetto collaterale, piuttosto che di -design). Non sto ripristinando quella parte della risposta, però, come chissà, potrebbe aiutare qualcuno. – oskarpearson
Sono stato morso da questo oggi. Questo post e la tua risposta mi hanno salvato la pancetta. Avevo dimenticato che uno degli svantaggi dei linguaggi dinamici è che non si hanno sempre gli stessi attributi in un oggetto ... il che potrebbe essere buono ma anche sbagliato :) –
È stato morso da questo oggi. Wow, questo è stato pubblicato qui nel 2009? Sono impressionato dal fatto che sia rimasto non fissato per così tanto tempo. – Trejkaz