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_attributes
only works properly on records that have already been saved.
> claim
=> #<Claim id: 51, tnc_accepted_at: nil, status_id: 4>
> claim.valid?
=> true
#=========
> claim.save # This makes all the difference!
(0.3ms) BEGIN
Claim Load (0.4ms) SELECT --blah blah blah
(1.0ms) INSERT INTO "claims" --blah blah blah
(14.8ms) COMMIT
=> true
#=========
> 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
# ... just as expected.
> claim.update_attributes! :terms_and_conditions => true
(0.3ms) BEGIN
ClaimItem Load (0.8ms) SELECT --blah blah blah
(0.8ms) UPDATE "claims" --blah blah blah
(11.4ms) COMMIT
=> true
# ... hooray!