Question

I've got a pretty basic problem but can't seem to get it to work right.

here's the setup -

class Recipe < ActiveRecord::Base
 has_many :recipeIngredients
 has_many :ingredients :through => :recipeIngredients
end

class Ingredient < ActiveRecord::Base
 has_many :recipeIngredients
 has_many :recipes :through => :recipeIngredients
end

class RecipeIngredients < ActiveRecord::Base
 belongs_to :recipe
 belongs_to :ingredients
end

Each ingredient has an ID and a name, Recipe has an ID and a Title, RecipeIngredients has recipe_id, ingredient_id, amount

When I attempt to render using

@recipe = Recipe.find(params[:id])
render :json => @recipe, :include => :ingredients

I get my ingredients, but can't access the amount or name from RecipeIngredients. - this outputs

{
    "list_items": {
        "id": 1,
        "title": "Foo",
        "description": null,
        "ingredients": [
            {
                "id": 1
            },
            {
                "id": 2
            },
            {
                "id": 3
            },
            {
                "id": 4
            }
        ]
    }
}

How can I make the relationship between ingredients and recipeIngredients so that when calling :ingredients I get something like -

{
 "id":1,
 "name":"foo",
 "amount":"2 oz"
}

thanks!

Was it helpful?

Solution

You didn't define many-to-many according to Rails. The correct solution is (file names should be as described):

app/models/recipe.rb

class Recipe < ActiveRecord::Base
  has_many :recipe_ingredients
  has_many :ingredients, :through => :recipe_ingredients
end

app/models/ingredient.rb

class Ingredient < ActiveRecord::Base
  has_many :recipe_ingredients
  has_many :recipes, :through => :recipe_ingredients
end

app/models/recipe_igredient.rb

class RecipeIngredient < ActiveRecord::Base
  belongs_to :recipe
  belongs_to :ingredient
end

Also verify, your join table defined, as following:

db/12345_create_recipe_ingredints.rb

class CreateRecipeIngredients < ActiveRecord::Migration
  def change
    create_table :recipe_ingredients, id: false do |t|
      t.references :recipe
      t.references :ingredient
    end
    add_index :recipe_ingredients, :recipe_id
    add_index :recipe_ingredients, :ingredient_id
  end
end

After doing this, make a test in your console:

recipe = Recipe.first # should contain data
igredient = Ingredient.first # should contain data
recipe.ingredients << ingredient
recipe.inspect

If everything works correctly and recipe.inspect contains ingredient, json should be correct

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top