# Has\_one, has\_many, habtm?

**URL:** <https://www.ruby-forum.com/t/has-one-has-many-habtm/104262>\
**Category:** Rails\
**Created:** [May 16, 2007, 3:10am UTC](https://www.ruby-forum.com/t/has-one-has-many-habtm/104262 "2007-05-16T03:10:11Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![kelleysislander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kelleysislander](https://www.ruby-forum.com/u/kelleysislander)\
**Post date:** [May 16, 2007, 3:10am UTC](https://www.ruby-forum.com/t/has-one-has-many-habtm/104262/1 "2007-05-16T03:10:11Z")

</div>

Let’s suppose I’m designing an app for defining and storing  
information about Widgets. Widgets have a number of properties. They  
have a color, a shape, a size, a weight, a texture, etc. Each of these  
properties is chosen from a pre-defined list of possibilities for that  
property.

My initial thought was that each property subclasses a parent property  
(via STI):

class WidgetProperty \< ActiveRecord::Base  
end

Its migration self.up would look something like this:

create\_table widget\_properties do |t|  
t.column :value, :string  
t.column :type, :string  
end

Presumably it’s subclasses would all be along these lines:

class WidgetColor \< WidgetProperty  
end

class WidgetShape \< WidgetProperty  
end

. . . and so on. In the properties database, we’d have tables defining  
properties such as:

:id =\> 1, :value =\> :blue, :type =\> ‘WidgetColor’  
:id =\> 2, :value =\> ‘yellow’, :type =\> ‘WidgetColor’  
. . .  
:id =\> 36, :value =\> ‘square’, :type =\> ‘WidgetShape’

There about two dozen different kinds of property, each with 6-8  
values. But essentially they’re all the same - just an id and a string  
value. What I haven’t yet figured out is the following:

1. Is STI really the way to go here? I’m not sure if it’s buying me  
anything or not.

2. In my Widget model class, should my Widgets “have\_one  
:widget\_color, have\_one :widget\_shape” and so on, or should they  
“have\_many :widget\_properties”? Or maybe they should  
“has\_and\_belongs\_to\_many :widget\_properties”?

Question 2 is where most of my confusion is. The properties aren’t  
really “things” themselves, they’re just attributes that are assigned  
to Widgets, and otherwise have no meaning. But many Widgets are going  
to share properties (for example, there will be a lot of square, blue  
Widgets), so the properties don’t exactly belong to the Widgets.

I have a feeling there is probably a pretty straightforward way to do  
this (since this situation isn’t exactly unique, I’m sure), but for  
whatever reason it isn’t coming to me. I’m hoping someone can toss me  
a lifeline here.

Thanks very much.

–  
Bill K.

---

<div class="post-metadata">

**Author:** ![kelleysislander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kelleysislander](https://www.ruby-forum.com/u/kelleysislander)\
**Post date:** [May 16, 2007, 6:06am UTC](https://www.ruby-forum.com/t/has-one-has-many-habtm/104262/2 "2007-05-16T06:06:14Z")

</div>

I’m not seeing the need to use associations in what you’re describing.  
Why not just a single Widget class? You can treat the properties as  
strings.

create\_table widgets do |t|  
t.column :name, :string  
t.column :color, :string  
t.column :shape, :string  
… and so on …  
end

You can limit them to a list of possibilities in the model itself.

class Widget \< ActiveRecord::Base  
validates\_presence\_of :name, :color, :shape  
validates\_inclusion\_of :color, :in =\> [‘blue’, ‘yellow’,  
‘red’ … ], :message =\> “invalid color”  
validates\_inclusion\_of :shape, :in =\> [‘square’, ‘round’,  
‘rectangular’ … ], :message =\> “invalid shape”  
end

In other words, since a Widget is the thing that has properties, as you  
point out, it might not make sense to treat the properties as things.  
If you  
still want to think of the individual instances of properties (so to  
speak) as  
things in their own right, you could still access them through find\_by  
methods:

blue\_widgets = Widget.find\_all\_by\_color(“blue”)

---

<div class="post-metadata">

**Author:** ![kelleysislander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kelleysislander](https://www.ruby-forum.com/u/kelleysislander)\
**Post date:** [May 16, 2007, 7:08am UTC](https://www.ruby-forum.com/t/has-one-has-many-habtm/104262/3 "2007-05-16T07:08:29Z")

</div>

On May 16, 12:06 am, Eleatic Ephesian \<rails-mailing-l…@andreas-  
[s.net](http://s.net)\> wrote:

> I’m not seeing the need to use associations in what you’re describing.  
> Why not just a single Widget class? You can treat the properties as  
> strings.
> 
> create\_table widgets do |t|  
> t.column :name, :string  
> t.column :color, :string  
> t.column :shape, :string  
> … and so on …  
> end

I see what you’re saying. The catch, though, is that I also need to be  
able to easily pull them out of the database to include them in forms  
(as members of select lists, groups of radio buttons, etc.), so that’s  
kind of why they’re going in their own table.

---

<div class="post-metadata">

**Author:** ![kelleysislander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kelleysislander](https://www.ruby-forum.com/u/kelleysislander)\
**Post date:** [May 16, 2007, 7:25am UTC](https://www.ruby-forum.com/t/has-one-has-many-habtm/104262/4 "2007-05-16T07:25:28Z")

</div>

Bill K. wrote:

> I see what you’re saying. The catch, though, is that I also need to be  
> able to easily pull them out of the database to include them in forms  
> (as members of select lists, groups of radio buttons, etc.), so that’s  
> kind of why they’re going in their own table.

OK. So you know what colors, etc., will be the only possibilities ahead  
of time? Then why not this?

colors(name)  
shapes(name)  
widgets(name, color\_id, shape\_id)

Color :has\_many =\> :widgets  
Shape :has\_many =\> :widgets  
Widget :belongs\_to =\> :color, :shape

Then, collection\_select for your selection lists, blue\_color.widgets  
for a list a of blue widgets, etc. Simpler, I think, than creating an  
abstract class called WidgetProperty.

---

<div class="post-metadata">

**Author:** ![kelleysislander](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f6c823/32.png) [@kelleysislander](https://www.ruby-forum.com/u/kelleysislander)\
**Post date:** [May 16, 2007, 1:29pm UTC](https://www.ruby-forum.com/t/has-one-has-many-habtm/104262/5 "2007-05-16T13:29:07Z")

</div>

On May 16, 1:25 am, Eleatic Ephesian \<rails-mailing-l…@andreas-  
[s.net](http://s.net)\> wrote:

> OK. So you know what colors, etc., will be the only possibilities ahead  
> of time?

Yes.

> Then, collection\_select for your selection lists, blue\_color.widgets  
> for a list a of blue widgets, etc. Simpler, I think, than creating an  
> abstract class called WidgetProperty.

It is a bit simpler, but it also means I’ll have a couple dozen tables  
with 6-8 rows in them. It isn’t a tragedy, but it seems a bit less  
than optimal. What about a combined approach:

class WidgetProperty \< ActiveRecord::Base  
end

create\_table :widget\_properties do |t|  
t.column :value, :string  
t.column :type, :string

class Color \< WidgetProperty  
end

class Shape \< WidgetProperty  
end

Color :has\_many =\> :widgets  
Shape :has\_many =\> :widgets  
Widget :belongs\_to =\> :color, :shape

I think then I can use a single table for all of my properties. Or am  
I missing something? Not having used STI before, I’m not sure if  
ActiveRecord will know that it needs to look in the widget\_properties  
table to find a Color or not. I suppose I could try it and find out.

Thanks for your advice so far.
