How to HABTM with STI?

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

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

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: [email protected]
[mailto:[email protected]] On Behalf Of Chris T
Sent: Friday, 30 June 2006 7:35 p.m.
To: [email protected]
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