has_one/belongs_to relationship failing.

I have an Ingredient which has a Measurement.

class Ingredient < ActiveRecord::Base
  has_one :measurement
  belongs_to :recipe

  accepts_nested_attributes_for :measurement

class Measurement < ActiveRecord::Base
  belongs_to :ingredient

The schemas appear right:

  create_table "ingredients", :force => true do |t|
    t.integer "measurement_id"
    t.integer "recipe_id"
    t.string "quantity"
    t.string "food"
    t.datetime "created_at"
    t.datetime "updated_at"

  create_table "measurements", :force => true do |t|
    t.string "size"
    t.float "quantity"
    t.string "abbreviation"
    t.string "measurement"
    t.string "measurement_type"
    t.string "equivalent"
    t.datetime "created_at"
    t.datetime "updated_at"

But I'm still getting this error preventing me from doing an
ingredient.measurement.abbreviation, but ingredient.measurement_id

ActiveRecord::StatementInvalid in Recipes#show

Showing /Users/mkidd/Sites/cookbook/app/views/recipes/show.html.erb
where line #14 raised:

SQLite3::SQLException: no such column: measurements.ingredient_id:
SELECT "measurements".* FROM "measurements" WHERE
("measurements".ingredient_id = 1) LIMIT 1

Extracted source (around line #14):

11: <% for ingredient in @recipe.ingredients%>
12: <li>
13: <%= ingredient.quantity %>
14: <%= ingredient.measurement %>
15: <%= ingredient.food %>
16: </li>
17: <% end %>

It is the belongs_to object that should have the foreign key, so
measurement should have an ingredient_id, not vice versa. Or the
relationship should be the other way round.


Colin Law wrote in post #989292:

You could have an ingredient_measures table that belongs_to a recipe
(recipe has_many ingredient_measures). Each ingredient_measures
record specifies an ingredient and a measure of that ingredient for
the recipe. So you would also need ingredient_measure belongs_to
ingredient and belongs_to measure and ingredient and both ingredient
and measure has_many ingredient_measures.

So for a recipe, @recipe, then @recipe.ingredient_measures will give
all the ingredients with their measures.

In effect this is a HABTM relationship between ingredient and recipe
through ingredient_measures, but there is probably no need to specify
it like that unless you need to iterate all ingredients for a
particular measure or vice versa, which I guess you probably don't