I'm trying to create a nested form in Rails 4. However, the nested attribute is not being saved to database. The error message that I am receiving is "param is missing or the value is empty". Based on the params output, I know that the following is wrong.
"recipe_ingredients_attributes"=>{"0"=>{"ingreident_name"=>"321",
"amount"=>"1",
"unit"=>"g"}},
It should be as follow:
"recipe_ingredients_attributes"=>{"recipe_id" => 1, ingreident_name"=>"321", "amount"=>"1", "unit"=>"g"},
Can someone please help me to solve this. Thanks.
Note: recipe_ingredients does not have it own controller
The following is the my code.
Parameters Output:
{"utf8"=>"✓",
"authenticity_token"=>"GPN4rrurH+77Z7QbQZSlguJE/HJvUCVJzVkAtmgiL39jZ/ouzbh53K4PCwdaXopB3vn+8jA0gRfRcahqWfj9kw==",
"recipe"=>{"name"=>"321",
"product_type"=>"Gelato",
"description"=>"321",
"steps"=>"321",
"note"=>"321",
"recipe_ingredients_attributes"=>{"0"=>{"ingreident_name"=>"321",
"amount"=>"1",
"unit"=>"g"}},
"create_date"=>"2015-08-01 16:10:08 -0700",
"last_modify"=>"2015-08-01 16:10:08 -0700"},
"commit"=>"create"}
/schema.rb
create_table "recipe_ingredients", force: :cascade do |t|
t.integer "recipe_id", limit: 4, null: false
t.string "ingreident_name", limit: 200, null: false
t.integer "amount", limit: 4, null: false
t.string "unit", limit: 45, null: false
end
create_table "recipes", force: :cascade do |t|
t.string "product_type", limit: 45, null: false
t.string "name", limit: 45, null: false
t.string "steps", limit: 500, null: false
t.string "note", limit: 500
t.date "create_date", null: false
t.datetime "last_modify", null: false
end
/models/recipe.rb
class Recipe < ActiveRecord::Base
has_many :recipe_ingredients, :dependent => :destroy
accepts_nested_attributes_for :recipe_ingredients
end
/models/recipe_ingredients.rb
class RecipeIngredient < ActiveRecord::Base
belongs_to :recipe
end
/recipe_controller.rb
class RecipeController < ApplicationController
def index #where the form is located
@test = Recipe.new
@test.recipe_ingredients.build
end
def createRecipe
@recipe = Recipe.new(recipe_params)
if @recipe.save
redirect_to recipe_path
else
render plain: 'plain text'
end
end
private
def recipe_params
params.require(:recipes).permit(:id, :product_type, :name, :steps, :note,
:create_date, :last_modify,
:recip_ingredients_attributes=> [:recipe_id, :ingreident_name,
:amount, :unit])
end
end
end
view for the form
<%= form_for @test, :url => {:action => "createRecipe"}, :html => {:method => "POST"} do |f| %>
Name
<br/>
<%= f.text_field :name %>
<br/>
Product Type
<br/>
<%= f.text_field :product_type %>
<br/>
Steps
<br/>
<%= f.text_area :steps, :size => "65x15", :maxlength => "5000" %>
<br/>
Notes
<br/>
<%= f.text_area :note, :size => "65x5", :maxlength => "5000" %>
<br/>
Ingridients
<br/>
<%= f.fields_for :recipe_ingredients do |builder| %>
<%= builder.text_field :ingreident_name %>
<%= builder.text_field :amount %>
<%= builder.text_field :unit %>
<% end %>
<%= f.hidden_field :create_date, :value => Time.now %>
<%= f.hidden_field :last_modify, :value => Time.now %>
<%= f.submit "create" %>
<% end %>
答案 0 :(得分:1)
Looks like you come from javascript background.
read
in all cases needs to be recipeIngredients