Newbie worries with "Developing Rails Applications on Max OSX Leopard"

Hello There,
As a new comer to RoR, I started to follow the article
http://developer.apple.com/tools/developonrailsleopard.html. In short
you create to entities and one one-to-many relation linking them.

Everything was good until the establishment of the relation. I am
unable to go any further than “Linking Models Together” : I can create
the “vendors” mentionned in the exemple, and I can get an “event” to
look to. But when I try to create an “expense”, I get a message
saying :

event.expenses.create(:vendor => vendor1, :amount => 75.00)
NoMethodError: undefined method expenses' for #<Event:0x125e008> from /Library/Ruby/Gems/1.8/gems/activerecord-2.0.2/lib/active_record/ attribute_methods.rb:205:in method_missing’
from (irb):2

Could anybody help me ? I have checked the classes files, everything
seems according to the article. I did checks on the database, the
table “expenses” has been created but is empty. The “id” fiels are
present in each of the tables… I don’t see where to look to now.

Thanks in advance,

Thierry

Thierry wrote:

event.expenses.create(:vendor => vendor1, :amount => 75.00)
NoMethodError: undefined method expenses' for #<Event:0x125e008> from /Library/Ruby/Gems/1.8/gems/activerecord-2.0.2/lib/active_record/ attribute_methods.rb:205:inmethod_missing’
from (irb):2

Could anybody help me ? I have checked the classes files, everything
seems according to the article. I did checks on the database, the
table “expenses” has been created but is empty. The “id” fiels are
present in each of the tables… I don’t see where to look to now.

Do you have the following in your Event class:

has_many :expenses

?
This is the line that give the Event class the method “expenses” which
links to the Expense class. And in the Expense class:

belongs_to :event

to get the map the other way around giving the Expense class the method
“event”.

Thierry

To easily remember what Mark told you, just remember that the foreign
key is always in the model that has the belongs_to relationship… When
I first started playing with AR, that little fact made everything much
more easier to comprehend…

hth

ilan

Mark,

Thanks for your answer. Precisely, it seems to me that I have
everything right. I put the code here :

===== > In the “event.rb” file :

class Event < ActiveRecord::Base
validates_presence_of :name
validates_numericality_of :budget, :greater_than => 0.0

has_many :expenses
has_many :vendors, :through => :expenses

def total_expenses
expenses.sum(:amount) || BigDecimal(“0.0”)
end

def budget_exceeded?
total_expenses > budget
end

end

===> In the expense.rb file :

class Expense < ActiveRecord::Base
belongs_to :event
belongs_to :vendor
end

===> In the vendor.rb file :

class Vendor < ActiveRecord::Base
has_many :expenses
has_many :events, :through => :expenses
end

Thanks again

That’s it :

Expense.column_names
=> [“id”, “event_id”, “vendor_id”, “amount”, “created_at”,
“updated_at”]

Event.column_names
=> [“id”, “name”, “budget”, “created_at”, “updated_at”]

Expense.column_names
=> [“id”, “event_id”, “vendor_id”, “amount”, “created_at”,
“updated_at”]

Vendor.column_names
=> [“id”, “name”, “email”, “created_at”, “updated_at”]

It looks fine too, doesn’t it ?

Thierry wrote:

That’s it :

Expense.column_names
=> [“id”, “event_id”, “vendor_id”, “amount”, “created_at”,
“updated_at”]

Event.column_names
=> [“id”, “name”, “budget”, “created_at”, “updated_at”]

It looks fine too, doesn’t it ?

Yes. Was the error produced in a console that you started after making
the extra changes to the Event and Expense models? In a console, the
models are loaded when first used only and if you change them then you
need to reload them. You can do this with:

reload!

or just by restarting the console (use “quit” to exit, then run the
console again).

Thierry wrote:

Thanks for your answer. Precisely, it seems to me that I have
everything right. I put the code here :

That looks fine. Can you post the results of running (in the
application console):

Event.column_names

and:

Expense.column_names

Just to confirm that these two models are both set up correctly too…

I did it as follows :

$ script/console
Loading development environment (Rails 2.0.2)

event = Event.find_by_name(‘Bienvenue’)
=> #<Event id: 4, name: “Bienvenue”, budget: #<BigDecimal:
125d57c,‘0.456E3’,4(8)>, created_at: “2008-03-05 17:33:11”,
updated_at: “2008-03-05 17:33:11”>

event.expenses.create(:vendor => vendor1, :amount => 75.00)
NoMethodError: undefined method expenses' for #<Event:0x125dd88> from /Library/Ruby/Gems/1.8/gems/activerecord-2.0.2/lib/active_record/ attribute_methods.rb:205:inmethod_missing’
from (irb):2

I am really lost…

SOLVED

In fact, I have been fooled by XCode that does not save the files when
it tells you that it does… I had to close completely XCode for some
modifications to be taken into account by rails. I have noticed this
when I had to restart my computer (battery low), my files where in an
old version. When I retyped the missing code I made typos, and I saw
them appear in the logs. The only solution to correct them has been to
close completely XCode and to execute a reload! in the console… A
bit strange.
Thanks to all and sorry for your time,

Thierry

I had this exact same problem. Found this page searching for a
solution to my “NoMethodError” blues. Had to close XCode and re-open
it for the changes to be recognized. That is a VERY annoying
problem.

Also had to quit the ruby console and restart it. Using the “reload!”
command mentioned above did not work.

Sorry if this is post is in the wrong place. I am a ROR newbie also
working thru the “Developing Rails Applications on Max OSX Leopard”
article. I am having a separate issue though.
I’m wondering if my version (Rails 2.1.1) differs from that in the
tutorial(2.0.2) in the way it returns a sum:

Tutorial:

event.expenses.sum(:amount)
=> #BigDecimal:1a04960,‘0.1E3’,4(8)

When I run this expression returns:

event.expenses.sum(:amount)
=> 200

Later when running unit tests:

require ‘test_helper’

class EventTest < ActiveSupport::TestCase
def test_budget
event = Event.new(:name => ‘Test Event’, :budget => 30.00)
event.expenses.build(:amount => 10.00)
event.expenses.build(:amount => 20.50)
assert event.save

assert_equal BigDecimal("30.50"), event.total_expenses
assert event.budget_exceeded?

end
end

I get the following failure:

  1. Failure:
    test_budget(EventTest)
    [./test/unit/event_test.rb:10:in test_budget' /Library/Ruby/Gems/1.8/gems/activesupport-2.1.1/lib/ active_support/testing/setup_and_teardown.rb:33:insend
    /Library/Ruby/Gems/1.8/gems/activesupport-2.1.1/lib/
    active_support/testing/setup_and_teardown.rb:33:in `run’]:
    <#BigDecimal:213bad0,‘0.305E2’,8(8)> expected but was
    <30.5>.

Are these the result of some casting error?

Thanks.