# How to HABTM with STI?

**URL:** <https://www.ruby-forum.com/t/how-to-habtm-with-sti/96610>\
**Category:** Rails\
**Created:** [June 30, 2006, 5:49am UTC](https://www.ruby-forum.com/t/how-to-habtm-with-sti/96610 "2006-06-30T05:49:54Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![adam](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/4af34b/32.png) [@adam](https://www.ruby-forum.com/u/adam)\
**Post date:** [June 30, 2006, 5:49am UTC](https://www.ruby-forum.com/t/how-to-habtm-with-sti/96610/1 "2006-06-30T05:49:54Z")

</div>

Hello all

This is my first post so excuse the basic question. (and any repeats I  
just  
got an email saying this post was too big so I have re-submitted a  
smaller  
version)

I was following the thread on  
[http://lists.rubyonrails.org/pipermail/rails/2006-May/038988.html](http://lists.rubyonrails.org/pipermail/rails/2006-May/038988.html)  
regarding  
the STI on HABTM for RoR.

I have a very similar problem and was hoping for some help.

I have the following models that employ single table inheritance and  
HABTM  
(see below for sql script showing tables). I read that the classes will  
inherit the HABTM relationship from the parent class. Eg Part should  
understand habtm because his father does. Is this correct?

class Product \< ActiveRecord::Base

```
  belongs_to :category

  has_and_belongs_to_many :items

```

end

class Item \< ActiveRecord::Base

has\_and\_belongs\_to\_many :products

end

class Part \< Item

end

class Accessory \< Item

end

I have created part and accessory controllers/crud views and have  
attempted  
to do the following but it doesn’t appear that the HABTM relationship is  
in  
place.

> From the products\_controller I attempt the following:

#populate collections for \_partials

@parts = @product.parts.find\_all

@accessories = @product.accessories.find\_all

But get the following error.

Undefined method `parts’

Any suggestions?

Regards,  
Adam

------------sql script

# ----------------------

# create tables

# ----------------------

CREATE TABLE `categories` (

CREATE TABLE `products` (

CREATE TABLE `items` (

CREATE TABLE `attachments` (

# ----------------------

# create join tables

# ----------------------

CREATE TABLE items\_products (

CREATE TABLE attachments\_products (

CREATE TABLE attachments\_items (

---

<div class="post-metadata">

**Author:** ![adam](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/4af34b/32.png) [@adam](https://www.ruby-forum.com/u/adam)\
**Post date:** [June 30, 2006, 9:38am UTC](https://www.ruby-forum.com/t/how-to-habtm-with-sti/96610/2 "2006-06-30T09:38:10Z")

</div>

Haven’t investigated this myself yet, but my guess is that there is no  
method ‘parts’, because that’s not how you’ve set up the relationship.  
Setting up an association (in this case a HABTM) adds a bunch of methods  
to the class (model), including one named after the other class that the  
association is with (or rather its downcased plural form in this case).  
So, as you’ve declared Product has\_and\_belongs\_to\_many \*:items \*you can  
do @items = :product.items but not @parts = @product.parts

Two suggestions (neither really thought through or tested). You may be  
able to declare an addition HABTM relationship with :parts, though you  
would have to specify the class, join table, and prob conditions too  
manually. Or alternatively you could do something like:  
@parts = @product.items.find(:all, :conditions =\>[“type = ‘Part’”])

You could obviously also wrap this up in a method as well to make it  
somewhat sweeter.

HTH

---

<div class="post-metadata">

**Author:** ![adam](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/4af34b/32.png) [@adam](https://www.ruby-forum.com/u/adam)\
**Post date:** [June 30, 2006, 2:12pm UTC](https://www.ruby-forum.com/t/how-to-habtm-with-sti/96610/3 "2006-06-30T14:12:20Z")

</div>

Thanks for the reply!

I just attempted to force the relationship through the :join\_table  
param.

Models now:

class Product \< ActiveRecord::Base

```
  has_and_belongs_to_many :parts,

                       :join_table=>'items_products'

```

End

class Item \< ActiveRecord::Base

end

class Part \< Item

has\_and\_belongs\_to\_many :products

end

But I get the following error =(

ActiveRecord::StatementInvalid in Products#show

Showing app/views/products/partials/\_product\_parts.rhtml where line #7  
raised:

Mysql::Error: #42S22Unknown column ‘items\_products.part\_id’ in ‘on  
clause’:  
SELECT \* FROM items INNER JOIN items\_products ON items.id =  
items\_products.part\_id WHERE (items\_products.product\_id = 1 ) AND (  
(items.`type` = ‘Part’ ) )

Extracted source (around line #7):

4:

5:

6:

7: \<% for part in @parts %\>

8:

9:

| \<%= link\_to part.cat\_number,

10: :controller =\> “parts”,

I was thinking I may have to use the following:

@product.items.find\_by\_type(‘Part’)

* * *

From: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Chris T  
Sent: Friday, 30 June 2006 7:35 p.m.  
To: removed\_email\_address@domain.invalid  
Subject: Re: [Rails] how to HABTM with STI ??

Haven’t investigated this myself yet, but my guess is that there is no  
method ‘parts’, because that’s not how you’ve set up the relationship.  
Setting up an association (in this case a HABTM) adds a bunch of methods  
to  
the class (model), including one named after the other class that the  
association is with (or rather its downcased plural form in this case).  
So,  
as you’ve declared Product has\_and\_belongs\_to\_many :items you can do  
@items  
= :product.items but not @parts = @product.parts

Two suggestions (neither really thought through or tested). You may be  
able  
to declare an addition HABTM relationship with :parts, though you would  
have  
to specify the class, join table, and prob conditions too manually. Or  
alternatively you could do something like:

@parts = @product.items.find(:all, :conditions =\>[“type = ‘Part’”])

You could obviously also wrap this up in a method as well to make it  
somewhat sweeter.

HTH

 |
