tags:

views:

26

answers:

2

For my recipe-sharing website, I want to create a database and CakePHP models for the recipes and their ingredients.

I created two tables: recipes and ingredients. The third table is a HABTM table for ingredients_recipes, which also stores the amount of ingredients needed for the recipes. How do I create a model for the third table?

The third table would look something like this:

recipe_id
ingredient_id
amount
measurement_unit

I also thought of adding another table for measurement_units to store all possible units (ex. tablespoon, tea spoon, cup, etc.). Would that be too much?

+2  A: 

HABTM, within Cake's ORM, is actually an abstraction of the following two model association structures (using your example):

Recipe
-> hasMany IngredientsRecipe
           -> belongsTo Ingredient

and

Ingredient
-> hasMany IngredientsRecipe
           -> belongsTo Recipe

The IngredientsRecipe model is inferred, and used only to link the two first-class models, Ingredient and Recipe.

However, in your case, you actually want IngredientsRecipe to be a first-class model, which breaks the HABTM abstraction. In fact, what you need to do is explicitly define the two association structures above, so that Cake treats the IngredientsRecipe model as a first-class citizen, allowing you to query against it, save records to it, etc.

Also, no, I don't think it's too much to create an additional MeasurementUnit model. It will provide you much more flexibility down the line.

Daniel Wright
I am sorry, I guess I am completely lost in all this. How do I explicitly define the two association structures? By creating the model php file, just like the files for ingredients and recipes?
Olga
Sorry to be so long getting back to you. Basically, you need to define three models instead of two, because you're not really joining `Recipe` and `Ingredient` directly together. Rather, you're joining `Recipe` to `RecipeElement` to `Ingredient`; and `Ingredient` to `RecipeElement` to `Recipe`. `Ingredient` and `Recipe` continue to fill the same role they do now, and `RecipeElement` comprises information about the specific measurements and units for each ingredient in a recipe. I hope that makes sense.
Daniel Wright
By way of explanation I have added an answer, but I doff my hat to Daniel ;)
Leo
+1  A: 

Think of it like this then treat it one chunk at a time:

`Recipe` (1)--(n) IngredientsRecipe (n)--(1) Ingredient
  1. In Recipe, create the association to IngredientsRecipe
  2. In Ingredient, create the association to IngredientsRecipe
  3. In IngredientsRecipe create the association to Recipe
  4. Still in IngredientsRecipe create the association to Ingredient

While you're doing it, forget about HABTM and think instead about hasMany and belongsTo

Incidentally, you are not bound to call the model IngredientsRecipe, that is just the default/convention.

When you're done, treat it like hasMany, belongsTo or HABTM as appropriate.

Leo
Thank you very much, I will start working on it
Olga