“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; amount_percent
errors.add_to_base('either amount OR amount_percent must be specified') if !amount &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.
