Topic: has_many :through Question

Hi,

I have been having some trouble trying to display the ingredients for a cocktail using a has_many :through relationship.

I am able to get the "id,name,description" by @cocktail.ingredients from the ingredients table or I can get "id, quantity, unit_of_measure" from the cocktail_ingredients table by @cocktail.cocktail_ingredients.

In the Cocktail view action I would like list each ingredient with its quantity, unit_of_measure, name and description.

How can I join each table to accomplish this?

Below is the code that I have.

Tables

   def self.up
      create_table :cocktails do |t|
         t.column :name, :string
         t.column :description, :text
         t.column :created_on, :datetime
         t.column :updated_on, :datetime
      end
   end

  def self.up
    create_table :cocktail_ingredients do |t|
       t.column :cocktail_id, :integer
       t.column :ingredient_id, :integer
       t.column :quantity, :integer
       t.column :unit_of_measure, :string
    end
  end

  def self.up
      create_table :ingredients do |t|
         t.column :name, :string
         t.column :description, :text
      end
   end


Models

class Cocktail < ActiveRecord::Base
   has_many :cocktail_ingredients
   has_many :ingredients, :through => :cocktail_ingredients

class Ingredient < ActiveRecord::Base
  has_many :cocktail_ingredients
  has_many :cocktails, :through => :cocktail_ingredients
end

class CocktailIngredient < ActiveRecord::Base
  belongs_to :cocktail
  belongs_to :ingredient
end

Cocktail Controller

 def show
   @cocktail = Cocktail.find(params[:id])
end

Thank you for any help,
Jeff

Re: has_many :through Question

You can loop through the cocktail_ingredients to get the quantity and unit_of_measure. And then for the name and description you can reference the ingredient through the cocktail_ingredient. Like this:

<h2>Ingredients</h3>
<% for cocktail_ingredient in @cocktail.cocktail_ingredients %>
<p>
  Name: <%=h cocktail_ingredient.ingredient.name %><br />
  Description: <%=h cocktail_ingredient.ingredient.description %><br />
  Quantity: <%= cocktail_ingredient.quantity %><br />
  Unit of Measurement: <%=h cocktail_ingredient.unit_of_measurement %>
</p>
<% end %>

Does that make sense? It's a little dizzying because the join table is called cocktail_ingredients. You may want to rename this to something more concise. Even if it doesn't describe it as well, it will make it more readable.

Railscasts - Free Ruby on Rails Screencasts

Re: has_many :through Question

Hi ryanb,

Thank you very much.

This worked perfectly and now makes sense to me!

I am going to take your advice about renaming cocktail_ingredients for readability.

Jeff