Sean_K
(Sean K)
May 24, 2009, 7:46am
1
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
Sean_K
(Sean K)
May 24, 2009, 3:54pm
4
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.
Sean_K
(Sean K)
May 24, 2009, 4:02pm
5
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.