I am having trouble with Rails’ save method; it seems to be failing when it should, but not succeeding when it should.
I have a Claim model, that can be saved with any Status, but if it is to be submitted (status_id == 5) then the terms and conditions have to be accepted.
validates :terms_and_conditions, :acceptance => {:accept => true, :if => :submitted?}
def submitted? # simplified for this example
status_id == 5
end
However, I am also storing the time that the terms were accepted (under db field tnc_accepted_at), and defining terms_and_conditions as the presence of this field. (This bit works fine, I’m just not sure if it’s relevant to my problem.)
def terms_and_conditions
tnc_accepted_at.present?
end
def terms_and_conditions=(bool) # browser will pass '0' or '1'
self.tnc_accepted_at = bool.in?([false, nil, 0, '', '0']) ? nil : DateTime.now
end
But here’s the rub. The claim starts off in this state:
claim
=> #<Claim id: 51, tnc_accepted_at: nil, status_id: 4>
claim.valid?
=> true
Then I try to submit it:
claim.update_attributes! :status_id => 5
(0.3ms) BEGIN
ClaimItem Load (1.5ms) SELECT --blah blah blah
Status Load (0.6ms) SELECT --blah blah blah
(0.4ms) ROLLBACK
ActiveRecord::RecordInvalid: Validation failed: Terms and conditions must be accepted
… which is perfect, but when I try to correct the error:
claim.update_attributes! :terms_and_conditions => true
(0.3ms) BEGIN
ClaimItem Load (1.1ms) SELECT --blah blah blah
(0.7ms) UPDATE "claims" --blah blah blah
(0.2ms) ROLLBACK
=> nil
… which is just weird! And I’ve noticed that I also get this any time I try to save the record, under whatever set of circumstances (using save, save!, update_attributes, update_attributes!, :tnc_accepted_at => DateTime.now, it doesn’t matter) – if it’s valid, it rolls back and returns nil; if it’s invalid, the error is raised as you would expect.
Naturally it’s something really simple, after I spent an entire day on it…
So it seems
update_attributesonly works properly on records that have already been saved.