RyanScottLewis
RyanScottLewis

Reputation: 14016

Rails Associations

I can't seem to wrap my mind around Rails associations. Let's say I have 3 tables. One for Users, one for Recipes, and one for Ingredients. Here's an example of the database (in yaml):

Users:
  id: 1
  email: funnyusername
  password: pass1234

Recipes:
  id: 1591
  user_id: 1
  name: Pizza Dough

Ingredients:
  id: 1
  name: Flour

  id: 2
  name: Water

  id: 3
  name: Yeast

Now how would I make it so that a User can have many Recipes, and a Recipe can have many Ingredients. And also be able to find all the Recipes each Ingredient is attached to?

For instance, funnyusername created the Recipe "Pizza Dough" which has the ingredients Flour, Water, and Yeast. Now when I search for Yeast, I would want it to come up with a list of Recipes containing Yeast.

Upvotes: 0

Views: 378

Answers (1)

Doug Hays
Doug Hays

Reputation: 1507

Here are the associations:

# In User.rb
has_many :recipes

# In Recipe.rb
belongs_to :user
has_and_belongs_to_many :ingredients

# In Ingredient.rb
has_and_belongs_to_many :recipes

Now, this assumes that there is an ingredients_recipes table with two columns, recipe_id & ingredient_id. So, with your example, you could find all recipes with Yeast this way:

@recipes = Ingredient.find(:all, :conditions => {:name=> 'Yeast'}).recipes;

In your situation, you have ingredients that show up in many recipes and recipes that have many ingredients. With Rails (actually ActiveRecord) Associations, this is Has and Belongs To Many (HABTM) is explained here

The convention here is that when you associate two tables with HABTM, you'll have a joining table with two columns, each pointing to the primary key of a table. This joining table does not itself have a corresponding Model. Finally, the naming convention of the table is that you join the two names of the tables that the join table joins (ingredients and recipes) in alphabetic order. In your example: ingredients_recipes. This of course can be overridden.

Upvotes: 3

Related Questions