“save!” not working (nothing persisted to DB) but return result is “nil” rather than an error message

I recently was stuck trying to work out why a “save!” on one of my models was not working. I had checked and verified that the model object was valid first. I checked the database directly and there were definitely no record being saved.

Console Output Highlight the Issue


>> a = Allocation.new
=> #<Allocation id: nil, transaction_id: nil, person_id: nil, recurring_id: nil, amount: nil, amount_percent: nil, created_at: nil, updated_at: nil>
>>
?> a.valid?
=> false
>> a.amount = 1
=> 1
>> a.transaction_id = 1
=> 1
>> a.person_id = 1
=> 1
>>
?> a.valid?
=> true
>>
?>
?> a.save
=> nil
>> a.save!
=> nil

SQL Commands Observed


Transaction Columns (0.003291)   SHOW FIELDS FROM `transactions`
  Transaction Load (0.001494)   SELECT * FROM `transactions` WHERE (`transactions`.`id` = 1) 

Model Code


class Allocation < ActiveRecord::Base
  belongs_to :person
  belongs_to :transaction

  validates_numericality_of :amount, :if => :amount
  validates_numericality_of :amount_percent, :if => :amount_percent

  private

  def validate
    errors.add_to_base('amount and amount_percent can not both be specified') if amount &amp;amp;amp;amp;&amp;amp;amp;amp; amount_percent
    errors.add_to_base('either amount OR amount_percent must be specified') if !amount &amp;amp;amp;amp;&amp;amp;amp;amp; !amount_percent
  end  

end

Can you see the issue? (I couldn’t)

Solution:Transaction is a reserved class in Rails, and it was the name of one of my models, in this case it was one that my “Allocation” model had an association with. The “belongs_to transaction” line was creating a “transaction” method for reading the association. This overwrote an internal method called transaction. The internal method just runs its block inside a database transaction and is used on saves etc… By replacing that with a transaction method that does nothing with the block you completely neutre activerecord.

For a list of Rails reserved words see: http://wiki.rubyonrails.org/rails/pages/ReservedWords

I’ll be starting the renaming of the model “transaction” that I had shortly :(

Acknowledgements:Ryan Bigg, Frederick Cheung and Chris Bartlett from the Rails mailing list. Thanks guys.

Comments are closed.