Any ideas on how to model this?

Hello,

I’m attempting to move beyond the Agile Web Dev w\Rails book and explore
writing some practice apps from scratch. I m attempting to model an
online t-shirt shop were customers can select from a variety of
different designs. Each design will be available in different colors
and each color will have different sizes. Also, I’d like to keep track
of the number of available shirts.

My most recent data modeling attempt consists of 3 tables and respective
columns:

  1. designs - name, description, picture, price.
  2. color - color, design_id
  3. size - size, color_id

The model associations are:
design - has_many :colors, has_many :sizes
color - has_many :sizes, belongs_to :designs
size - belongs_to :color, :belongs_to :design

SO far, so good! The problem is having to keep an inventory of the
number of available shirts (i.e. quantity). I have a 4th table called
‘quantity’ which has the following columns: quantity, design_id,
color_id, size_id since it isn’t strictly associated with a single
design, color or size but all three.

But… From here I’m lost. I have tried using a HABTM association
between the design table and quantity table but something just didn’t
seem right. So I’m asking for help. What is the best way to model
this? Does the ‘quantity’ table need to be on it’s own or can I perhaps
rework it into the other 3 tables?

Any help is greatly appreciated!!!

Hi Richard,

Richard D. wrote:

I m attempting to model an online t-shirt shop

My most recent data modeling attempt consists
of 3 tables and respective columns:

  1. designs - name, description, picture, price.
  2. color - color, design_id
  3. size - size, color_id

The model associations are:

… largely irrelevant until you have all the models you need. If
you’re
modeling a t-shirt shop, one might expect a t-shirt model. That might
have
a quantity-on-hand attribute. Of course, that’s just one way to look at
it.

hth,
Bill

On 11/15/06, Richard D. [email protected] wrote:

My most recent data modeling attempt consists of 3 tables and respective
columns:

  1. designs - name, description, picture, price.
  2. color - color, design_id
  3. size - size, color_id

The model associations are:
design - has_many :colors, has_many :sizes
color - has_many :sizes, belongs_to :designs
size - belongs_to :color, :belongs_to :design

The relationships are not right. You can break them easily by creating
a color belonging_to one design, and a size belonging to the same
color, but a different design. If you drew some sort of model diagram,
you would see that you have created a triangle between the three
entities, which is (almost) always a Very Bad Idea. You would also
have to model the same color (e.g. Blue) multiple times - one for each
design; and model each size (S/M/L) once for each color/design
combination.

You have a need for an explicit join model. There are a few different
ways of modelling this, but let’s introduce a new model class calle
Variation - this is a fairly common term in this kind of situation.
Normally, each Variation of a product in a shop will have it’s own
unique product number of some sort.
Your model might look like this:

Variation
belongs_to :design
belongs_to :color
belongs_to :size

Design
has_many :variations
has_many :colors, :through=>:variations
has_many :sizes, :through=>:variations

This way, while logically your Design model offers the same access to
the colors and sizes, you have created a derived relationship
between the classes, which is much preferrable to the Triangle Of
Doom.

To get a list of colors for a chosen design is simple:
some_design.colors

To get a list of all variations for a design and a color (from which
you can get the sizes):
some_design.variations.find_by_color_id(the_color_id)

Or get the sizes directly:
some_design.variations.find_by_color_id(the_color_id).collect { |v|
v.size }

The last two should probably be implemented as methods on the Design
class (get_variations_for_color(color), get_sizes_for_color(color))

You could then ad the stock quantities to the Variaion model, or model
them in a separate table with a has_one relationship.

Cheers,
Max

Awesome info Max! I’m working on modeling a scenario of my own and
although it’s a little bit different from this one, reading your post
on how to tackle this problem was VERY insightful.

Thank you very much. This is just what I was looking for!!!