belongs_to not saving foreign key

Under Rails 2.3.2 using a completely brand new project, I have 2 models:

class Author < ActiveRecord::Base   # name:string end

class Book < ActiveRecord::Base   # title:string   belongs_to :author # author_id end

And a simple test where i create a Book with an Author using the belongs_to and then update the foreign key directly:

require 'test_helper'

class BookTest < ActiveSupport::TestCase   test "foreign key updating" do     a1 = Author.create! :name => 'author 1'     b = Book.create! :title => 'rails', :author => a1     a2 = Author.create! :name => 'author 2'     b.update_attributes! :author_id => a2.id     assert_equal a2.id, b.author_id # author_id is still a1.id!   end end

The test fails on the last line. Am i doing something wrong or is this expected behaviour?

your Author should :have_many :books

You also want to do something like this:

dave = Author.create(:name => ‘Dave Thomas’)

pickaxe = dave.books.build(:title => ‘Programming Ruby 1.9’)

Jeff Schoolcraft is right. Your Author model should have this line

:has_many :books

In faat you should specify all the db relations in your model files, all of them.

cheers

Thanks for the replies. However, changing the Author to:

class Author < ActiveRecord::Base   has_many :books end

doesn't change the outcome of the test. The problem that i'm having seems to be that the foreign key (Book.author_id) is not being updated by update_attributes. This smells like a bug to me.

You are correct, Jeff, setting the author using the create method on a has_many works:

  test "something" do     a1 = Author.create! :name => 'author 1'     b = a1.books.create! :title => 'rails'     a2 = Author.create! :name => 'author 2'     b.update_attributes! :author_id => a2.id     assert_equal a2.id, b.author_id   end

And so does setting the author via the foreign key:

  test "something" do     a1 = Author.create! :name => 'author 1'     b = Book.create! :title => 'rails', :author_id => a1     a2 = Author.create! :name => 'author 2'     b.update_attributes! :author_id => a2.id     assert_equal a2.id, b.author_id   end

So why doesn't it like it when the belongs_to is used? Seems odd.

before the update_attributes line, try adding

b = Book.find(:first, "title => 'rails'")

then

b.update_attributes! :author_id => a2.id

It seems that update_attributes will work from found object, not newly created object, and this is normally done under update action of controller

Sean K wrote:

Sean K wrote:

Under Rails 2.3.2 using a completely brand new project, I have 2 models:

class Author < ActiveRecord::Base # name:string end

class Book < ActiveRecord::Base # title:string belongs_to :author # author_id end

And a simple test where i create a Book with an Author using the belongs_to and then update the foreign key directly:

require 'test_helper'

class BookTest < ActiveSupport::TestCase test "foreign key updating" do    a1 = Author.create! :name => 'author 1'    b = Book.create! :title => 'rails', :author => a1    a2 = Author.create! :name => 'author 2'    b.update_attributes! :author_id => a2.id    assert_equal a2.id, b.author_id # author_id is still a1.id! end end

The test fails on the last line. Am i doing something wrong or is this expected behaviour?

Actually when you update the attribute for the one object, the ram- cached copy isn't updated for the other (association), so you need to
reload it.

b.reload

you're probably better off saying:

b.author = a2

I think.