# Getting the associated model in a join table

**URL:** <https://www.ruby-forum.com/t/getting-the-associated-model-in-a-join-table/164874>\
**Category:** Rails\
**Created:** [April 6, 2009, 10:43pm UTC](https://www.ruby-forum.com/t/getting-the-associated-model-in-a-join-table/164874 "2009-04-06T22:43:05Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![mhfs](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b2d939/32.png) [@mhfs](https://www.ruby-forum.com/u/mhfs)\
**Post date:** [April 6, 2009, 10:43pm UTC](https://www.ruby-forum.com/t/getting-the-associated-model-in-a-join-table/164874/1 "2009-04-06T22:43:05Z")

</div>

Let’s say we have the following models:

Product \< ActiveRecord::Base  
has\_many :products\_suppliers  
has\_many :suppliers, :through =\> :products\_supplier

Supplier \< ActiveRecord::Base  
has\_many :products\_suppliers  
has\_many :products, :through =\> :products\_supplier

ProductsSupplier \< ActiveRecord::Base  
belongs\_to :supplier  
belongs\_to :product  
end

Let’ say we have this data in the products\_suppliers table:

| supplier\_id | product\_id |  
| 1 | 2 |  
| 1 | 1 |  
| 2 | 2 |  
| 2 | 1 |

So when I do this:

@suppliers = Product.find(1).suppliers, it will return an array with the  
suppliers with id 1 and 2.

Let’s say I do this:

@supplier = @suppliers[0] #Which is the supplier with id = 1, the one  
fetched from the (supplier\_id = 1, product\_id = 2) record in the  
products\_suppliers table. Ok, now I got a single instance of a supplier.  
**What I want is to get the product\_id it was associated with in the  
products\_suppliers table.** (product\_id = 2), might be missing something  
simple, but I can’t seem to find a way to do that.

Any help appreciated!

Thanks,

Marcelo.

---

<div class="post-metadata">

**Author:** ![mhfs](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b2d939/32.png) [@mhfs](https://www.ruby-forum.com/u/mhfs)\
**Post date:** [April 7, 2009, 12:02am UTC](https://www.ruby-forum.com/t/getting-the-associated-model-in-a-join-table/164874/2 "2009-04-07T00:02:44Z")

</div>

Actually the question would be better put this way:

Having a has\_one association via a link table (in this case  
products\_supplier).

Thanks.

On Mon, Apr 6, 2009 at 3:41 PM, Marcelo de Moraes S.  
\<removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![mhfs](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b2d939/32.png) [@mhfs](https://www.ruby-forum.com/u/mhfs)\
**Post date:** [April 7, 2009, 4:48am UTC](https://www.ruby-forum.com/t/getting-the-associated-model-in-a-join-table/164874/3 "2009-04-07T04:48:09Z")

</div>

I couldn’t really get your question, but I think that what you are  
trying to do here is to create a many to many relationship.

Rails actually provides the has\_and\_belongs\_to\_many association for  
this very purpose, which should help you with what you are asking (I  
think).

> **[Active Record Associations — Ruby on Rails Guides](https://guides.rubyonrails.org/association_basics.html#choosing-between-has-many-through-and-has-and-belongs-to-many)**
>
> Active Record AssociationsThis guide covers the association features of Active Record.After reading this guide, you will know: How to declare associations between Active Record models. How to understand the various types of Active Record...

On Apr 7, 6:01 am, Marcelo de Moraes S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![mhfs](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b2d939/32.png) [@mhfs](https://www.ruby-forum.com/u/mhfs)\
**Post date:** [April 7, 2009, 7:36pm UTC](https://www.ruby-forum.com/t/getting-the-associated-model-in-a-join-table/164874/4 "2009-04-07T19:36:56Z")

</div>

Hmm, maybe I’m complicating things. Maybe a delegate to the Product  
class  
(to get the product\_id) would solve this… hmm, I will try that and let  
you  
guys know. Well, amazing how the fact of writing to the mailing list  
helps  
to find the solution by yourself 🙂

Thanks!

Marcelo.

On Tue, Apr 7, 2009 at 12:28 PM, Marcelo de Moraes S. \<

---

<div class="post-metadata">

**Author:** ![mhfs](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b2d939/32.png) [@mhfs](https://www.ruby-forum.com/u/mhfs)\
**Post date:** [April 7, 2009, 7:29pm UTC](https://www.ruby-forum.com/t/getting-the-associated-model-in-a-join-table/164874/5 "2009-04-07T19:29:17Z")

</div>

Hello Jaryl, thanks for the reply,

habtm is equivalent to has\_many :through. just that the join table is  
not an  
entity by itself, this I know 🙂

So, I will try to explain through an example:

Let’s say we have a products table:

| id | name | price |  
| 1 | a | 2.50 |  
| 2 | b | 1.50 |

A suppliers table

| id | name |  
| 1 | s\_a |  
| 2 | s\_b |

So the idea is: A product may be supplied by many different suppliers.  
So,  
indeed, it is a has\_and\_belongs\_to\_many relationship. The thing is, the  
relationship by itself defines the type of the supplier (if it’s either  
a  
vendor or a manufacturer), since we have:

products\_suppliers table:  
| id | supplier\_id | product\_id | supplier\_type |  
| 1 | 1 | 1 | “vendor” |  
| 2 | 1 | 2 | “manufacturer”|

So, in tis case, supplier s\_a is a “vendor” of product a and a  
“manufacturer” of product b.

Product \< ActiveRecord::Base  
has\_many :products\_suppliers  
has\_many :suppliers, :through =\> :products\_suppliers  
end

Supplier \< ActiveRecord::Base  
has\_many :products\_suppliers  
has\_many :products, :through =\> :products\_suppliers  
end

ProductsSupplier \< ActiveRecord::Base  
belongs\_to :product  
belongs\_to :supplier  
end

So let’s take this code

p = Product.find(1)

What I need is a specific products\_suppliers related to specific combo  
of  
(supplier\_id,product\_id) keys, so I can get the supplier\_type data  
related  
to this product+supplier. However, I the has\_many relationship in  
Supplier  
reaturns all the products\_suppliers that has supplier\_id == the id of  
this  
supplier – To get the specific products\_supplier I would also need the  
id  
of the product that owns this supplier, but I can’t get it. So, the  
first  
thing I though was something like has\_one :through. That’s why I said, a  
has\_one relationship through a link table. The thing is, I need the  
product\_id that owns this supplier from the supplier model. I might as  
well  
just leave AR and do some raw SQL, or maybe use sql :select statemente  
in  
the association to fetch the type from the link table into the  
association.

Does that make sense?

Thanks,

Marcelo.

---

<div class="post-metadata">

**Author:** ![mhfs](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b2d939/32.png) [@mhfs](https://www.ruby-forum.com/u/mhfs)\
**Post date:** [April 8, 2009, 8:05am UTC](https://www.ruby-forum.com/t/getting-the-associated-model-in-a-join-table/164874/6 "2009-04-08T08:05:11Z")

</div>

I don’t think a delegate would work. Okay, just to recap on the  
database structure:

products  
| id | name | price |  
| 1 | a | 2.50 |  
| 2 | b | 1.50 |

suppliers  
| id | name |  
| 1 | s\_a |  
| 2 | s\_b |

products\_suppliers  
| id | supplier\_id | product\_id | supplier\_type |  
| 1 | 1 | 1 | “vendor” |  
| 2 | 1 | 2 | “manufacturer”|

Firstly, I don’t think that ‘products\_suppliers’ is a good name since  
this form is only a requirement for HABTM to work. It should be more  
descriptive of the relationship, but your call.

Okay, so I believe that you want to do something like this:

p = Product.first

p.vendors # =\> [#\< Supplier id: 1, name: “s\_a”\>, #\<Supplier id: 2,  
name: “s\_b”\>]  
p.manufacturer # =\> #\< Supplier id: 1, name: “s\_a”\>

You might want to try this:

class Product \< ActiveRecord::Base  
has\_many :products\_suppliers  
has\_many suppliers, :through =\> products\_suppliers

named\_scope :vendors, :conditions =\> [“supplier\_type = ?”, “vendor”]  
named\_scope :manufacturer, :conditions =\> [“supplier\_type = ?”,  
“manufacturer”]  
end

This does not restrict the manufacturer to a one-to-many relationship,  
so you will have to ensure that each product will have only one  
manufacturer (you can do this pretty easily with some validations).

---

<div class="post-metadata">

**Author:** ![mhfs](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b2d939/32.png) [@mhfs](https://www.ruby-forum.com/u/mhfs)\
**Post date:** [April 8, 2009, 5:15am UTC](https://www.ruby-forum.com/t/getting-the-associated-model-in-a-join-table/164874/7 "2009-04-08T05:15:35Z")

</div>

On Apr 7, 1:28 pm, Marcelo de Moraes S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> of the product that owns this supplier, but I can’t get it. So, the first  
> thing I though was something like has\_one :through. That’s why I said, a  
> has\_one relationship through a link table. The thing is, I need the  
> product\_id that owns this supplier from the supplier model. I might as well  
> just leave AR and do some raw SQL, or maybe use sql :select statemente in  
> the association to fetch the type from the link table into the association.
> 
> Does that make sense?

Maybe this is too obvious, but given the example above, couldn’t you  
just use:

p.products\_suppliers.find\_by\_supplier\_id(some\_supplier\_id)

That will give you the supplier that you’re looking for.

BTW, I’d recommend a different name for the supplier\_type column -  
that pattern (same as the foreign key, with \_type instead of \_id) is  
the Rails convention for single table inheritance, which is NOT what  
you’re looking for here. It shouldn’t cause a problem, but the AR  
association code is known to sometimes get really weird indigestion  
from that situation…

Hope this helps,

–Matt J.
