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


#1

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

Macintosh-2:myequity greg$ cat app/models/allocation.rb

== Schema Information

Schema version: 20081128104846

Table name: allocations

id :integer(4) not null, primary key

transaction_id :integer(4) not null

person_id :integer(4) not null

recurring_id :integer(4)

amount :decimal(9, 2)

amount_percent :decimal(9, 2)

created_at :datetime

updated_at :datetime

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 && amount_percent
errors.add_to_base(‘either amount OR amount_percent must be
specified’)
if !amount && !amount_percent
end

end


#2

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 **

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 && amount_percent
errors.add_to_base(‘either amount OR amount_percent must be
specified’)
if !amount && !amount_percent
end

end

On Fri, Dec 12, 2008 at 5:09 PM, Greg H. <


#3

Transaction is a reserved class in Rails.

Ryan B.
Freelancer
http://frozenplague.net


#4

On 14 Dec 2008, at 10:54, Ryan B. wrote:

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


#5

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

On Sun, Dec 14, 2008 at 11:37 PM, Frederick C. <


#6

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

On Mon, Dec 15, 2008 at 7:39 AM, Greg H. <


#7

On 14 Dec 2008, at 21:50, Greg H. wrote:

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


#8

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)

On Mon, Dec 15, 2008 at 7:59 AM, Frederick C. <


#9

On Dec 15, 10:59 am, Frederick C. removed_email_address@domain.invalid
wrote:

On 14 Dec 2008, at 21:50, Greg H. wrote:

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

Not that I know of.

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


#10

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:

On Mon, Dec 15, 2008 at 7:24 PM, Chris B.