How to deal with this code?

Hi,everyone
Here is my model code—>

has_many :authors_books
has_many :authors, :through => :authors_books

belongs_to :book
belongs_to :author

has_many :authors_books
has_many :books, :through => :authors_books

I use the authors_books to associate book and author.

And then ,I write a unit test,book_test.rb---->the code like follow

def test_ferret
 Book.rebuild_index

 assert Book.find_with_ferret("Pride and Prejudice")
 assert_difference Book, :count do
  book = Book.new(:title => 'The Success of Open Source',
                           :published_at => Time.now, :page_count =>
500,
                           :price => 59.99, :isbn => '0-647-01292-5')
  book.authors << Author.create(:first_name => "Steven", :last_name =>
"Weber")
  book.publisher = Publisher.find(1)
  assert book.valid?
  book.save

  assert_equal 1, Book.find_with_ferret("Open Source").size
  assert_equal 1,Book.find_with_ferret("Steven Weber").size
   end
 end

When I run my test,and goes wrong .Like this—>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

  1. Error:
    test_ferret(BookTest):
    ActiveRecord::HasManyThroughCantAssociateNewRecords: Cannot associate
    new record
    s through ‘Book#authors_books’ on ‘#’. Both records must have an id in
    order to
    create the has_many :through record associating them.
    C:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/
    active_record/associat
    ions/has_many_through_association.rb:52:in <<' test/unit/book_test.rb:87:intest_ferret’
    ./test/unit/…/test_helper.rb:41:in assert_difference' test/unit/book_test.rb:82:intest_ferret’
    C:/Ruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/
    active_support/testin
    g/default.rb:7:in `run’
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    Yeah ,I know my test code was wrong ? But I don’t know how to alter my
    code !
    Could you give me a favor ? Thanks a lot !

fireflyman wrote:

Hi,everyone
Here is my model code—>

has_many :authors_books
has_many :authors, :through => :authors_books

belongs_to :book
belongs_to :author

has_many :authors_books
has_many :books, :through => :authors_books

I wonder… Try adding “belongs_to :author” and “belongs_to :book” and
try again.

Hi –

On Mon, 7 Sep 2009, fireflyman wrote:

has_many :authors_books
assert Book.find_with_ferret(“Pride and Prejudice”)

new record
s through ‘Book#authors_books’ on ‘#’. Both records must have an id in
order to
create the has_many :through record associating them.

Just looking at it quickly I suspect that it’s because you’re trying
to add an Author to an unsaved Book record, and that it’s impossible
for the system to add a row to authors_books because it doesn’t have
the necessary information (since unsaved records don’t have id’s).

David


David A. Black / Ruby Power and Light, LLC / http://www.rubypal.com
Ruby/Rails training, mentoring, consulting, code-review
Latest book: The Well-Grounded Rubyist (The Well-Grounded Rubyist)

September Ruby training in NJ has been POSTPONED. Details to follow.

So,Could you help me deal with my code ?

On Tue, Sep 8, 2009 at 9:46 PM, Frederick C.
<[email protected]

wrote:

new record

Latest book: The Well-Grounded Rubyist (The Well-Grounded Rubyist)

September Ruby training in NJ has been POSTPONED. Details to follow.


Sons of Gondor, of Rohan, my brothers!
I see in your eyes the same fear that would take the heart of me.
A day may come when the courage of men fails when we forsake our friends
and
break all bonds of fellowship.
But this is not this day.
And hour of wolves and shattered shields when the age of Men comes
crashing
down. But this is not this day!
This day we fight! By all that you hold dear on this good earth, I bid
you
stand! Men of the West!

On 8 Sep 2009, at 13:44, David A. B

order to
create the has_many :through record associating them.

Just looking at it quickly I suspect that it’s because you’re trying
to add an Author to an unsaved Book record, and that it’s impossible
for the system to add a row to authors_books because it doesn’t have
the necessary information (since unsaved records don’t have id’s).

Rails 2.1 (or was it 2.2?) made has many through a lot more sane in
that respect.

Fred

On Sep 9, 8:19 am, Pascal F. [email protected] wrote:

the id of both, the author and the book. With the book id being nil…
I think you get the point.

Or upgrade to a version of rails that doesn’t require this.

Fred

On Sep 9, 3:33 am, fireflyman [email protected] wrote:

So,Could you help me deal with my code ?

David already gave you the answer, you are trying to add a
has_many :through associated record to an unsaved record. The error
message is pretty much telling you that “Cannot associate
new records through ‘Book#authors_books’ on ‘#’. Both records must
have an id in order to create the has_many :through record associating
them.”. The association is made through the author_books table with
the id of both, the author and the book. With the book id being nil…
I think you get the point.

If you use Book.new (and thats what you are doing in your test), the
new books id is still nil because it hasn’t been saved to the database
yet. Replace Book.create and you should be fine (as long as your
validations don’t fail).

– pascal