# How to deal with this code?

**URL:** <https://www.ruby-forum.com/t/how-to-deal-with-this-code/175067>\
**Category:** Rails\
**Created:** [September 7, 2009, 9:13am UTC](https://www.ruby-forum.com/t/how-to-deal-with-this-code/175067 "2009-09-07T09:13:08Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![fireflyman](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/43a26b/32.png) [@fireflyman](https://www.ruby-forum.com/u/fireflyman)\
**Post date:** [September 7, 2009, 9:13am UTC](https://www.ruby-forum.com/t/how-to-deal-with-this-code/175067/1 "2009-09-07T09:13:08Z")

</div>

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

```auto
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:in`test\_ferret’  
./test/unit/…/test\_helper.rb:41:in `assert_difference' test/unit/book_test.rb:82:in`test\_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 !

---

<div class="post-metadata">

**Author:** ![fireflyman](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/43a26b/32.png) [@fireflyman](https://www.ruby-forum.com/u/fireflyman)\
**Post date:** [September 8, 2009, 2:37pm UTC](https://www.ruby-forum.com/t/how-to-deal-with-this-code/175067/2 "2009-09-08T14:37:42Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![fireflyman](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/43a26b/32.png) [@fireflyman](https://www.ruby-forum.com/u/fireflyman)\
**Post date:** [September 8, 2009, 2:46pm UTC](https://www.ruby-forum.com/t/how-to-deal-with-this-code/175067/3 "2009-09-08T14:46:44Z")

</div>

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](http://www.rubypal.com)  
Ruby/Rails training, mentoring, consulting, code-review  
Latest book: The Well-Grounded Rubyist ([The Well-Grounded Rubyist](http://www.manning.com/black2))

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

---

<div class="post-metadata">

**Author:** ![fireflyman](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/43a26b/32.png) [@fireflyman](https://www.ruby-forum.com/u/fireflyman)\
**Post date:** [September 9, 2009, 3:35am UTC](https://www.ruby-forum.com/t/how-to-deal-with-this-code/175067/4 "2009-09-09T03:35:57Z")

</div>

So,Could you help me deal with my code ?

On Tue, Sep 8, 2009 at 9:46 PM, Frederick C.  
\<removed\_email\_address@domain.invalid

> wrote:

> > > new record
> 
> > Latest book: The Well-Grounded Rubyist ([The Well-Grounded Rubyist](http://www.manning.com/black2))
> > 
> > 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!

---

<div class="post-metadata">

**Author:** ![fireflyman](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/43a26b/32.png) [@fireflyman](https://www.ruby-forum.com/u/fireflyman)\
**Post date:** [September 8, 2009, 4:32pm UTC](https://www.ruby-forum.com/t/how-to-deal-with-this-code/175067/5 "2009-09-08T16:32:06Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![fireflyman](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/43a26b/32.png) [@fireflyman](https://www.ruby-forum.com/u/fireflyman)\
**Post date:** [September 9, 2009, 9:41am UTC](https://www.ruby-forum.com/t/how-to-deal-with-this-code/175067/6 "2009-09-09T09:41:16Z")

</div>

On Sep 9, 8:19 am, Pascal F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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

---

<div class="post-metadata">

**Author:** ![fireflyman](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/43a26b/32.png) [@fireflyman](https://www.ruby-forum.com/u/fireflyman)\
**Post date:** [September 9, 2009, 9:21am UTC](https://www.ruby-forum.com/t/how-to-deal-with-this-code/175067/7 "2009-09-09T09:21:56Z")

</div>

On Sep 9, 3:33 am, fireflyman [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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
