R. K. wrote in post #987926:
I'm attempting to make a basic CRUD/data entry cookbook. I've got a
recipe model that is composed of other models. I'm intending of using a
single form to create the recipes such that n ingredients and n
instructions can be associated to a single recipe.
I understand why it's not happening I just don't know how to make it
stop.
This is what I have so far as far as models and schema.rb:
class Direction < ActiveRecord::Base
belongs_to :recipe
validates :number, :presence => true
validates :instruction, :presence => true
def step
"#{number}.) #{instruction}"
end
end
class Ingredient < ActiveRecord::Base
has_one :measurement
belongs_to :recipe
validates :measurement, :presence => true
validates :quantity, :presence => true
validates :food, :presence => true
end
class Measurement < ActiveRecord::Base
belongs_to :ingredient
end
class Recipe < ActiveRecord::Base
has_many :ingredients
has_many :directions
validates :title, :presence => true
validates :description, :presence => true
accepts_nested_attributes_for :ingredients, :reject_if => proc { |a|
a[:food].blank? }
#accepts_nested_attributes_for :ingredients, :reject_if => proc { |a|
a[:food].blank? }
#we want to resuse ingredients if possible
accepts_nested_attributes_for :directions
#accepts_nested_attributes_for :directions, :reject_if => proc { |a|
a[:instruction].blank? }, :allow_destroy => true
#there should not be an issue with deleting directions associated to a
deleted recipe
#Ruby Programming/Syntax/Method Calls - Wikibooks, open books for an open world
end
# This file is auto-generated from the current state of the database.
Instead
# of editing this file, please use the migrations feature of Active
Record to
# incrementally modify your database, and then regenerate this schema
definition.
#
# Note that this schema.rb definition is the authoritative source for
your
# database schema. If you need to create the application database on
another
# system, you should be using db:schema:load, not running all the
migrations
# from scratch. The latter is a flawed and unsustainable approach (the
more migrations
# you'll amass, the slower it'll run and the greater likelihood for
issues).
#
# It's strongly recommended to check this file into your version control
system.
ActiveRecord::Schema.define(:version => 20110314191853) do
create_table "directions", :force => true do |t|
t.integer "recipe_id"
t.integer "number"
t.text "instruction"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "ingredients", :force => true do |t|
t.integer "measurement_id"
t.string "quantity"
t.string "food"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "measurements", :force => true do |t|
t.string "size"
t.float "quantity"
t.datetime "created_at"
t.datetime "updated_at"
t.string "abbreviation"
t.string "measurement"
t.string "measurement_type"
t.string "equivalent"
end
create_table "recipes", :force => true do |t|
t.integer "ingredient_id"
t.integer "direction_id"
t.string "title"
t.text "description"
t.datetime "created_at"
t.datetime "updated_at"
t.string "source"
t.string "image"
t.string "cooktime"
end
create_table "sessions", :force => true do |t|
t.string "session_id", :null => false
t.text "data"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "sessions", ["session_id"], :name =>
"index_sessions_on_session_id"
add_index "sessions", ["updated_at"], :name =>
"index_sessions_on_updated_at"
end
Basically, children need to know their parents. Take a look in the log
at the queries generated, and you'll see items like:
Querying to show a recipe with id = 1:
SELECT 'directions'.* FROM 'directions' WHERE ('directions'.recipe_id =
1)
So:
Recipe (top of the food chain - haha)
# table has no <model>_id fields
has_many :ingredients
has_many :directions
Ingredient
belongs_to :recipe # table must have recipe_id
has_one :measurement
Measurement
belongs_to :ingredient # table must have ingredient_id
Direction
belongs_to :recipe # table must have recipe_id
That should make your app happier.