views:

22

answers:

1

I am building a recipe app where a user can view recipes, list ingredients, get a shopping list, etc. etc.

Each Recipe is made of steps, each step has ingredients, and each ingredient has a grocery.

I was quite sure that the way to create these links was through the models, so my models look like this

class Recipe < ActiveRecord::Base
    has_many :steps,    :dependent => :destroy
    has_many :ingredients, :through => :steps
    has_many :groceries, :through => :ingredients
end

class Step < ActiveRecord::Base
  belongs_to :recipe
  has_many :ingredients, :dependent => :destroy
  has_many :groceries, :through => :ingredients
  accepts_nested_attributes_for :ingredients
end

class Ingredient < ActiveRecord::Base
    belongs_to :step
    belongs_to :recipe
    has_one :grocery
end

class Grocery < ActiveRecord::Base
    has_and_belongs_to_many :ingredients
        has_and_belongs_to_many :steps, :through => :ingredients
        has_and_belongs_to_many :recipes, :through => :ingredients
end

I can output debug @recipe.steps, @recipe.ingredients, but @recipe.groceries returns

uninitialized constant Recipe::Grocery

I think this is an issue with the joins, but I don't see why I should need to specify the join in the controller.

The controller is simply

def show
    @recipe = Recipe.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @recipe }
    end
  end

Am i looking for my error in the right place? or am I misinterpreting the error??

+2  A: 

I actually wrote a blog post about this a while back. The problem is that you can't daisy-chain has_many :through associations in Rails. Here's a link to my article explaining it:

http://kconrails.com/2010/01/28/nesting-has_many-through-relationships-in-ruby-on-rails/

The quick answer is that you can use the nested_has_many_through plugin to do this. A word of caution, though - the more you chain together, the slower and more complex the database hits are going to get. Good luck!

Jaime Bellmyer
Hi, I think I answered your question. Can you please accept my answer so I get credit? Thanks!
Jaime Bellmyer