# Why does this happen

**URL:** <https://www.ruby-forum.com/t/why-does-this-happen/163048>\
**Category:** Rails\
**Created:** [March 16, 2009, 11:41pm UTC](https://www.ruby-forum.com/t/why-does-this-happen/163048 "2009-03-16T23:41:26Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![ball](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/858c86/32.png) [@ball](https://www.ruby-forum.com/u/ball)\
**Post date:** [March 16, 2009, 11:41pm UTC](https://www.ruby-forum.com/t/why-does-this-happen/163048/1 "2009-03-16T23:41:26Z")

</div>

Quick question, using ActiveRecord,

catBike = Category.new(:name =\> “Bikes”)  
catBike.save

p = Product.new(:name =\> “Bike”, :price =\> 900)  
p.categories \<\< catBike  
p.save

p.categories now has TWO catBike

however, if I move the save before adding the categories it is fine.

I am curious why this happens. Thanks!

---

<div class="post-metadata">

**Author:** ![ball](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/858c86/32.png) [@ball](https://www.ruby-forum.com/u/ball)\
**Post date:** [March 17, 2009, 12:51am UTC](https://www.ruby-forum.com/t/why-does-this-happen/163048/2 "2009-03-17T00:51:44Z")

</div>

> p.categories now has TWO catBike

Because \<\< does not ask questions. It just adds a catBike. If you  
already had  
one, now you have two.

You might need some combination of these:

a :unique =\> true on the habtm (spelling?)  
a unique key (index) on the database

---

<div class="post-metadata">

**Author:** ![ball](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/858c86/32.png) [@ball](https://www.ruby-forum.com/u/ball)\
**Post date:** [March 17, 2009, 5:12am UTC](https://www.ruby-forum.com/t/why-does-this-happen/163048/3 "2009-03-17T05:12:38Z")

</div>

It didn’t exist before hand. ActiveRecord is triggering two inserts. I  
have included a full example and the SQL

catBike = Category.new(:name =\> “Bikes”)  
catBike.save

p = Product.new(:name =\> “Cannondale Bike”, :price =\> 1000)  
p.save  
p.categories \<\< catBike # This works great.

p = Product.new(:name =\> “Trek Bike”, :price =\> 900)  
p.categories \<\< catBike # this causes two entriens to be created  
p.save

Category Create (1.0ms) INSERT INTO `categories` (`name`) VALUES  
(‘Bikes’)  
Product Create (0.0ms) INSERT INTO `products` (`name`, `price`)  
VALUES(‘Cannondale Bike’, 1000)  
SQL (0.0ms) COMMIT  
SQL (0.0ms) BEGIN  
categories\_products Columns (10.0ms) SHOW FIELDS FROM  
`categories_products`  
SQL (1.0ms) INSERT INTO `categories_products` (`product_id`,  
`category_id`) VALUES (1, 1)  
SQL (0.0ms) COMMIT  
SQL (0.0ms) BEGIN  
SQL (0.0ms) COMMIT  
SQL (0.0ms) BEGIN  
Product Create (1.0ms) INSERT INTO `products` (`name`, `price`)  
VALUES(‘Trek Bike’, 900)  
categories\_products Columns (7.0ms) SHOW FIELDS FROM  
`categories_products`  
SQL (1.0ms) INSERT INTO `categories_products` (`product_id`,  
`category_id`) VALUES (2, 1)  
categories\_products Columns (7.0ms) SHOW FIELDS FROM  
`categories_products`  
SQL (0.0ms) INSERT INTO `categories_products` (`product_id`,  
`category_id`) VALUES (2, 1)  
SQL (0.0ms) COMMIT

---

<div class="post-metadata">

**Author:** ![ball](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/858c86/32.png) [@ball](https://www.ruby-forum.com/u/ball)\
**Post date:** [March 17, 2009, 10:48am UTC](https://www.ruby-forum.com/t/why-does-this-happen/163048/4 "2009-03-17T10:48:42Z")

</div>

I replicated 2 scenareos and neither of them do what you have  
described:

has and belongs to many scenario

== models

class Product  
has\_and\_belongs\_to\_many :categories  
end

class Category  
has\_and\_belongs\_to\_many :products  
end

== db

create\_table “categories”, :force =\> true do |t|  
t.string “name”  
end

create\_table “categories\_products”, :id =\> false, :force =\> true do |  
t|  
t.integer “product\_id”  
t.integer “category\_id”  
end

create\_table “products”, :force =\> true do |t|  
t.string “name”  
t.integer “price”  
end

== test

> > p = Product.new :name =\> “cool bike”, :price =\> 123  
> > =\> #\<Product id: nil, name: “cool bike”, price: 123\>
> 
> > p.categories \<\< c  
> > =\> [#\<Category id: 1, name: “bikes”\>]
> 
> > p.save  
> > =\> true
> 
> > p.categories  
> > =\> [#\<Category id: 1, name: “bikes”\>]

Same thing with has\_many :through. which leads me to believe you  
havent set your relationships right. Could you show us the mdoel and  
table code plz?

---

<div class="post-metadata">

**Author:** ![ball](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/858c86/32.png) [@ball](https://www.ruby-forum.com/u/ball)\
**Post date:** [March 17, 2009, 4:13pm UTC](https://www.ruby-forum.com/t/why-does-this-happen/163048/5 "2009-03-17T16:13:12Z")

</div>

On 17 Mar., 15:18, ball [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Thanks. I am sure it is something I am missing. I am trying to learn  
> about SQL and Rails.  
> Here is the script I am using. I am really just trying to create a  
> script that explores all of the database relationships and how to  
> implement them in Rails.
> 
> The code:[http://rafb.net/p/iUgqjX46.html](http://rafb.net/p/iUgqjX46.html)
> 
> The output and SQL:[http://rafb.net/p/tpvlVc44.html](http://rafb.net/p/tpvlVc44.html)

I believe it’s because the \<\< method both append the specified object  
to the collection (in your case, a Category to a Products categories  
collection) AND saves it afterwards. So saving the product twice might  
cause the category to be added twice. At least that’s what I think. So  
in your case I’ld do like this:

cat\_bike = Category.new(:name =\> “Bikes”)  
cat\_bike.save

p = Product.new(:name =\> “Bike”, :price =\> 900)  
p.save  
p.categories \<\< cat\_bike

To avoid duplication in your categories table. Hope that was  
helpful. 🙂

–  
Cheers,  
David K.  
[http://twitter.com/rubyguy](http://twitter.com/rubyguy)

---

<div class="post-metadata">

**Author:** ![ball](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/858c86/32.png) [@ball](https://www.ruby-forum.com/u/ball)\
**Post date:** [March 17, 2009, 11:11pm UTC](https://www.ruby-forum.com/t/why-does-this-happen/163048/6 "2009-03-17T23:11:33Z")

</div>

Thanks David, I poked around in the debugger a bit after your  
suggestion, and honestly, I don’t understand Ruby code well enough to  
make sense of it all. Not to mention, I kept running into

> > No sourcefile available for (eval)

However, what I did find was that the \<\< operator, did not issue the  
insert command in the “double” case. The save command after the fact  
seemed to issue the two inserts. Now this confuses me completely.

So, if anyone can explain why/how this could happen, that would be  
great.

---

<div class="post-metadata">

**Author:** ![ball](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/858c86/32.png) [@ball](https://www.ruby-forum.com/u/ball)\
**Post date:** [March 17, 2009, 3:18pm UTC](https://www.ruby-forum.com/t/why-does-this-happen/163048/7 "2009-03-17T15:18:56Z")

</div>

Thanks. I am sure it is something I am missing. I am trying to learn  
about SQL and Rails.  
Here is the script I am using. I am really just trying to create a  
script that explores all of the database relationships and how to  
implement them in Rails.

The code: [http://rafb.net/p/iUgqjX46.html](http://rafb.net/p/iUgqjX46.html)

The output and SQL: [http://rafb.net/p/tpvlVc44.html](http://rafb.net/p/tpvlVc44.html)

---

<div class="post-metadata">

**Author:** ![ball](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/858c86/32.png) [@ball](https://www.ruby-forum.com/u/ball)\
**Post date:** [March 18, 2009, 7:24pm UTC](https://www.ruby-forum.com/t/why-does-this-happen/163048/8 "2009-03-18T19:24:18Z")

</div>

RAFB apparently drops files after 24 hours - any chance you could put  
those examples up someplace (gist or pastie, for instance) with a  
little more persistence?

Without seeing the code, it’s hard to even guess what’s going on. But  
I seem to recall seeing similar behavior when I had code saving an  
associated record in before\_save, which then got picked up again by  
the association save callbacks.

–Matt J.

---

<div class="post-metadata">

**Author:** ![ball](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/858c86/32.png) [@ball](https://www.ruby-forum.com/u/ball)\
**Post date:** [March 20, 2009, 9:35pm UTC](https://www.ruby-forum.com/t/why-does-this-happen/163048/9 "2009-03-20T21:35:48Z")

</div>

On 18 Mar., 19:23, Matt J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> RAFB apparently drops files after 24 hours - any chance you could put  
> those examples up someplace (gist or pastie, for instance) with a  
> little more persistence?
> 
> Without seeing the code, it’s hard to even guess what’s going on. But  
> I seem to recall seeing similar behavior when I had code saving an  
> associated record in before\_save, which then got picked up again by  
> the association save callbacks.

I totally agree. Ball, you should really paste some code somewhere, so  
we can try to figure out what’s wrong here.

–  
Cheers,  
David K.  
[http://twitter.com/rubyguy](http://twitter.com/rubyguy)
