why is wrong with this code - the model "save!" method does not seem to give a correct response back?

Hi,

I have a model for which when I go to save an item it doesn’t seem to get saved. In the console I don’t get a “record not saved” error??? But rather the response seems to give me back a Transaction object (i.e. for which the saved Allocation object has a relationship with)? Any ideas why?

CONSOLE OUTPUT
?> 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.transaction_id = 1784
=> 1784

a.person_id = 1
=> 1

a.amount = 100
=> 100

a.valid?
=> true

a.save!
=> #<Transaction id: 1784, transaction_date: “2009-02-04”, bank_account_id: 5, category_id: 6, recurring_id: 3, amount: #BigDecimal:22291e0,‘0.0’,4(8), balance: #BigDecimal:2229190,‘0.1E4’,4(12), description: “food”, notes: nil, created_at: “2008-12-08 21:21:17”, updated_at: “2008-12-08 21:21:17”, projection: true>

a
=> #<Allocation id: nil, transaction_id: 1784, person_id: 1, recurring_id: nil, amount: #BigDecimal:2218160,‘0.1E3’,4(8), amount_percent: nil, created_at: nil, updated_at: nil>

MODEL

still stuck here

When I create a new “allocation” model object, I check it is valid OK, but when I “save!” it I just get a “nil”? What would this imply. There’s no error as such. It is true to say that I populated the non-null columns with relationship with ID’s of just “1” (i.e. didn’t ensure there was actually a matching record in their tables). Also the DB doesn’t have foreign key constraints for these relationships. Questions here:

Q1 - Does rails check to see that there is a valid object in an association present before allowing the save? (i.e. via the fact that the model has a “belongs_to” in it?

Q2 - If it does do this check what would be the expected output from Rails the object wasn’t there in the associated table (e.g. if one put manually a bad reference ID in)? Would it be “nil” as I got? There wouldn’t be a more specific exception raised? especially if one is using the “save!” method?

*** CONSOLE OUTPUT ***

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 FROM ./SCRIPT/SERVER WHEN I DID THE “a.save!” ***

Transaction Columns (0.003291) SHOW FIELDS FROM transactions

Transaction Load (0.001494) SELECT * FROM transactions WHERE (transactions.id = 1)

** Model code **

Transaction is a reserved class in Rails.

Transaction is a reserved class in Rails.

That's not quite the whole story. The issue that if you have
belongs_to transaction in your model that creates a transaction method
for reading the association.
This overwrites 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.
As of http://github.com/rails/rails/commit/455c7f9e37fda2969e52698b766413fc735eb488
  this won't be a problem any more.

Fred

wow - thanks heaps

For the future should there been a way for me to have worked this out myself? i.e. without knowing the internals of Rails, but by using log information, trying things in console etc

Tks

PS. Just adding another followup question if I may:

Q1 - For the future should there been a way for me to have worked this out
myself? i.e. without knowing the internals of Rails, but by using log
information, trying things in console etc

Q2 - Is there a list of “reserved names” available somewhere one could use as a check for model names?

Q3 - Can I assume the best step for me is to just rename my model, and work this change through my code?

Q4 - Wondering if it would be a good idea to Rails to check for “bad” model names and give a warning? (similar to warnings like, you not on the optimal mysql driver)

Thanks again

PS. Just adding another followup question if I may:

Q1 - For the future should there been a way for me to have worked
this out myself? i.e. without knowing the internals of Rails, but
by using log information, trying things in console etc

might have found it stepping through save with the debugger. I ran
into this problem myself many moons ago and probably worked it out
like that.

Q2 - Is there a list of "reserved names" available somewhere one
could use as a check for model names?

Not that I know of.

Q3 - Can I assume the best step for me is to just rename my model,
and work this change through my code?

certainly the easiest way out, until 2.3 hits the streets.

Q4 - Wondering if it would be a good idea to Rails to check for
"bad" model names and give a warning? (similar to warnings like,
you not on the optimal mysql driver)

Rails does try (eg with dangerous attribute names)

Fred

excellent thanks - not sure how long I would have looked for this one

I’ve tried to summarise this on my blog for furture reference at http://blog.gregnet.org/?p=17 (i.e. on http://blog.gregnet.org)

http://wiki.rubyonrails.org/rails/pages/ReservedWords
(Google is your friend.)

great - interesting how I’ve been using the “transaction” model for some months but it is only since I’ve had a new model that has an association with it (i.e. the “allocation” model in this case) that I’ve noticed an issue… :slight_smile: