# How can I set up relations for these models?

**URL:** <https://www.ruby-forum.com/t/how-can-i-set-up-relations-for-these-models/61063>\
**Category:** Rails\
**Created:** [May 19, 2006, 7:36pm UTC](https://www.ruby-forum.com/t/how-can-i-set-up-relations-for-these-models/61063 "2006-05-19T19:36:12Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [May 19, 2006, 7:36pm UTC](https://www.ruby-forum.com/t/how-can-i-set-up-relations-for-these-models/61063/1 "2006-05-19T19:36:12Z")

</div>

Hello!

I have a legacy DB and want to use ActiveRecord for it.  
However, I can’t set up a relation correctly.

Here’s table spec:

[products]  
id  
name  
price

[subproducts]  
product\_id  
subproduct\_id

Some example data:

[products]  
1, “Computer”, 500.00  
2, “Monitor”, 200.00  
3, “Printer”, 100.00  
4, “System”, 700.00  
5, “System2”, 650.00

“System” is made up of “Computer”, “Monitor”, and “Printer”  
“System2” is made up of “Computer” and “Printer”

So [subproducts] table will have the following rows.

4, 1  
4, 2  
4, 3  
5, 1  
5, 2

“Computer” can be sold by itself or as a part of “System”.

class Product \< ActiveRecord::Base  
#???  
end

How do I set up relations?  
It seems like a many-to-many relation.  
But I’m stuck here.

Thansk.  
Sam

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [May 19, 2006, 7:53pm UTC](https://www.ruby-forum.com/t/how-can-i-set-up-relations-for-these-models/61063/2 "2006-05-19T19:53:53Z")

</div>

First thing I would do is try this:

class Product \< ActiveRecord::Base  
has\_many :subproducts  
end

class Subproduct \< ActiveRecord::Base  
belongs\_to :product  
set\_primary\_key “subproduct\_id”  
end

Now I don’t know what subproducts are but I assume that ‘product\_id’  
is the parent id and subproduct\_id is the primary key of the table but  
a foreign key to the actual product itself.

That gets tricky but not really impossible.

p = Product.find(1)  
new\_product = Product.create :name=\>“Computer”, :price=\>500  
p.subproducts \<\< SubProduct.create :subproduct\_id =\>new\_product.id

And you could pretty that up by making your own add\_subproduct method  
on your model. A rushed and untested example might be this:

class Product \< ActiveRecord::Base  
has\_many :subproducts

def add\_subproduct(product\_id)  
self.subproducts \<\< Subproduct.create :subproduct\_id =\> product\_id  
end

def remove\_subproduct(product\_id)  
self.subproducts.remove(product\_id)  
end  
end

p = Product.find(1)  
s = Product.find(2)  
p.add\_subproduct s.id  
p.remove\_subproduct s.id

Would that work?

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [May 19, 2006, 8:09pm UTC](https://www.ruby-forum.com/t/how-can-i-set-up-relations-for-these-models/61063/3 "2006-05-19T20:09:49Z")

</div>

Hi, Brian,  
Thank you for the answer.

I need to make one thing clear.

subproducts table is just a join table which doesn’t have a primary  
key(id).  
See the example data for subproducts.

product\_id, subproduct\_id  
4, 1  
4, 2  
4, 3  
5, 1  
5, 2

subproduct\_id can’t be a primary\_key just by itself.  
Primary key would be the composite of product\_id and subproduct\_id.

This is a many-to-many relation.  
But the difference is that this relation is between one table instead of  
two.

Usually a many-to-many is like between student-to-class.  
But my case is like product-to-product.

What do you think?

Sam

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [May 19, 2006, 9:54pm UTC](https://www.ruby-forum.com/t/how-can-i-set-up-relations-for-these-models/61063/4 "2006-05-19T21:54:00Z")

</div>

Oh, I think that it’s exactly what I want.  
Thanks!

Sam

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [May 19, 2006, 9:11pm UTC](https://www.ruby-forum.com/t/how-can-i-set-up-relations-for-these-models/61063/5 "2006-05-19T21:11:37Z")

</div>

Do you mean to say that it is possible for a subproduct to belong to  
more than one product? Cos that’s what this implies.

That’s easy though… you should look here:

[http://rails.techno-weenie.net/tip/2006/4/12/self\_referential\_many\_to\_many\_relationships](http://rails.techno-weenie.net/tip/2006/4/12/self_referential_many_to_many_relationships)

That will do it for you then!

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [May 19, 2006, 10:00pm UTC](https://www.ruby-forum.com/t/how-can-i-set-up-relations-for-these-models/61063/6 "2006-05-19T22:00:33Z")

</div>

Sam K. wrote:

> Oh, I think that it’s exactly what I want.  
> Thanks!

That should work fine if all you need is a join table. If you want to  
keep additional attributes in the subproducts table (like maybe number  
of units?), you’ll want to use a self-referential join model.

[http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through](http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through)

–  
Josh S.  
[http://blog.hasmanythrough.com](http://blog.hasmanythrough.com)

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [May 20, 2006, 1:50am UTC](https://www.ruby-forum.com/t/how-can-i-set-up-relations-for-these-models/61063/7 "2006-05-20T01:50:22Z")

</div>

Josh S. wrote:

> Sam K. wrote:
> 
> > Oh, I think that it’s exactly what I want.  
> > Thanks!
> 
> That should work fine if all you need is a join table. If you want to  
> keep additional attributes in the subproducts table (like maybe number  
> of units?), you’ll want to use a self-referential join model.
> 
> [http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through](http://blog.hasmanythrough.com/articles/2006/04/21/self-referential-through)

Wow, how did you know that?  
I need additional attributes in the subproducts table.  
I was thinking about it and you already answered.

Thank you so much.  
Sam

---

<div class="post-metadata">

**Author:** ![ssk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/82dd89/32.png) [@ssk](https://www.ruby-forum.com/u/ssk)\
**Post date:** [May 20, 2006, 9:03am UTC](https://www.ruby-forum.com/t/how-can-i-set-up-relations-for-these-models/61063/8 "2006-05-20T09:03:28Z")

</div>

Sam K. wrote:

> Wow, how did you know that?  
> I need additional attributes in the subproducts table.  
> I was thinking about it and you already answered.

I’ve been answering questions on this list for a while. I guess I’m  
learning what usually comes next 🙂

cheers!

–  
Josh S.  
[http://blog.hasmanythrough.com](http://blog.hasmanythrough.com)
