# (Many-to-many)-to many

**URL:** <https://www.ruby-forum.com/t/many-to-many-to-many/86577>\
**Category:** Rails\
**Created:** [February 23, 2007, 11:50am UTC](https://www.ruby-forum.com/t/many-to-many-to-many/86577 "2007-02-23T11:50:16Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![mastica](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a87d85/32.png) [@mastica](https://www.ruby-forum.com/u/mastica)\
**Post date:** [February 23, 2007, 11:50am UTC](https://www.ruby-forum.com/t/many-to-many-to-many/86577/1 "2007-02-23T11:50:16Z")

</div>

I’m very new at rails and wondering if ActiveRecord supports (many-to-  
many)-to many relationships.

For example: I have recipes, ingredients, and cookingmethods. Recipes  
have many ingredients, and ingredients are in many recipes. For each  
ingredient in a recipe, there is a different cooking method. For  
example, potatoes in a salad are diced, but potatoes in potato chips  
are sliced. Example database tables:

recipes: id, name  
recipes\_ingredients: id, recipe\_id, ingredient\_id  
ingredients: ingredient\_id, name  
cookingmethods: id, name  
recipes\_ingredients\_cookingmethods: recipe\_ingredient\_id,  
cookingmethod\_id

I looked at through associations, but those seemed to deal only with  
many-to-many relationships.

Thanks,

Gerry

---

<div class="post-metadata">

**Author:** ![mastica](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a87d85/32.png) [@mastica](https://www.ruby-forum.com/u/mastica)\
**Post date:** [February 23, 2007, 12:13pm UTC](https://www.ruby-forum.com/t/many-to-many-to-many/86577/2 "2007-02-23T12:13:24Z")

</div>

I’m, looking at something similar, try this  
([http://groups.google.com/group/rubyonrails-talk/browse\_frm/thread/](http://groups.google.com/group/rubyonrails-talk/browse_frm/thread/)  
b4e27651fb149e48?lnk=igtc)  
and let me know how you get on? I’d be interested in seeing your  
model and any extra finder methods you add…

Feel free to gTalk me

J

---

<div class="post-metadata">

**Author:** ![mastica](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a87d85/32.png) [@mastica](https://www.ruby-forum.com/u/mastica)\
**Post date:** [February 23, 2007, 3:05pm UTC](https://www.ruby-forum.com/t/many-to-many-to-many/86577/3 "2007-02-23T15:05:44Z")

</div>

To do this, you have your ingredients, recipes and cooking\_methods  
tables,  
as well as a join table… let’s call this recipe\_ingredients. This  
would  
have foreign key columns, one for each of the other tables.

Recipe  
has\_many :recipe\_ingredients  
has\_many :ingredients, :through =\> :recipe\_ingredients  
has\_many :cooking\_methods, :through =\> :recipe\_ingredients

Ingredient  
has\_many :recipe\_ingredients  
has\_many :recipes, :through =\> :recipe\_ingredients  
has\_many :cooking\_methods, :through =\> :recipe\_ingredients

CookingMethod  
has\_many :recipe\_ingredients  
has\_many :ingredients, :through =\> :recipe\_ingredients  
has\_many :recipes, :through =\> :recipe\_ingredients

RecipeIngredient  
belongs\_to :recipe  
belongs\_to :ingredient  
belongs\_to :cooking\_method

There. It’s quite easy really. You just have to break down three-way  
relationships into two way ones, and that’ll solve any (database)  
relationship problems.

Hope this helps,  
-Nathan

---

<div class="post-metadata">

**Author:** ![mastica](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a87d85/32.png) [@mastica](https://www.ruby-forum.com/u/mastica)\
**Post date:** [February 23, 2007, 3:07pm UTC](https://www.ruby-forum.com/t/many-to-many-to-many/86577/4 "2007-02-23T15:07:45Z")

</div>

\*this would have three foreign key columns, one for each of the other  
tables.

---

<div class="post-metadata">

**Author:** ![mastica](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a87d85/32.png) [@mastica](https://www.ruby-forum.com/u/mastica)\
**Post date:** [February 23, 2007, 9:13pm UTC](https://www.ruby-forum.com/t/many-to-many-to-many/86577/5 "2007-02-23T21:13:52Z")

</div>

Thanks. I’ll try that out. I’ve never gotten such a quick answer from  
posting a programming question on any forum before.

Gerry

---

<div class="post-metadata">

**Author:** ![mastica](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a87d85/32.png) [@mastica](https://www.ruby-forum.com/u/mastica)\
**Post date:** [February 23, 2007, 3:54pm UTC](https://www.ruby-forum.com/t/many-to-many-to-many/86577/6 "2007-02-23T15:54:55Z")

</div>

I’d be interested to see how the and controllers and views should be  
constructed for this model

J

---

<div class="post-metadata">

**Author:** ![mastica](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a87d85/32.png) [@mastica](https://www.ruby-forum.com/u/mastica)\
**Post date:** [February 24, 2007, 12:17pm UTC](https://www.ruby-forum.com/t/many-to-many-to-many/86577/7 "2007-02-24T12:17:11Z")

</div>

My inner database normalization conscience has some misgivings about  
this schema. Suppose the number of cooking methods is large compared  
to the number of recipe/ingredients. So potatoes in potato chips can  
be sliced, diced, grated… Then I’ll end up duplicating the recipe/  
ingredients foreign keys a lot in the join table.

Suppose further that people can comment on each recipe/ingredient/  
cooking method combination. I would have to add a “comments” column to  
recipes\_ingredients. Then for each comment, I’ll have to duplicate the  
keys for recipes/ingredients/cookingmethod…this is clearly  
unnormalized.

So I think my original schema gives me more flexibility in the long  
run. Any way I can get rails to work with the original schema (see  
first post in thread)?

Thanks for your help.

Gerry

---

<div class="post-metadata">

**Author:** ![mastica](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a87d85/32.png) [@mastica](https://www.ruby-forum.com/u/mastica)\
**Post date:** [February 26, 2007, 5:37am UTC](https://www.ruby-forum.com/t/many-to-many-to-many/86577/8 "2007-02-26T05:37:46Z")

</div>

On 2/24/07, mastica [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> keys for recipes/ingredients/cookingmethod…this is clearly  
> unnormalized.

normalisation is not necessarily the best design in all cases… but I  
digress…

> So I think my original schema gives me more flexibility in the long  
> run. Any way I can get rails to work with the original schema (see  
> first post in thread)?

Of course. You need to promote your ingredient/cookingmethod table to  
a proper first-class model. If you find yourself talking (or thinking)  
about a join table a lot, it’s usually a sign that it wants to be a  
model.

You’ll also want to read up on has\_many :through.

Let’s call that model Preparation. You then have:

class Ingredient  
has\_many :preparations  
has\_many :cooking\_methods, :through=\>:preparations  
has\_many :recipes, :through=\>:preparations  
end

class Recipe  
has\_and\_belongs\_to\_many :preparations  
has\_many :ingredients, :through=\>:preparations  
end

class CookingMethod  
has\_many :preparations  
has\_many :ingredients, :through=\>:preparations  
end

class Preparation  
has\_and\_belongs\_to\_many :recipes  
belongs\_to :ingredient  
belongs\_to :cooking\_method  
end

5 tables total, one for each of the models, plus a preparations\_recipes  
table.

–max

---

<div class="post-metadata">

**Author:** ![mastica](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/a87d85/32.png) [@mastica](https://www.ruby-forum.com/u/mastica)\
**Post date:** [March 12, 2007, 3:07pm UTC](https://www.ruby-forum.com/t/many-to-many-to-many/86577/9 "2007-03-12T15:07:43Z")

</div>

Im getting an error when running an app under fastCGI

file …/public\_html/…/config/…/tmp/sessions//ruby\_sess.(whatver) not  
readable

app works fine under regular cgi.

What would cause this?
