Rails 4 Nested Form- param is missing or the value is empty:

时间:2015-07-28 23:33:06

标签: ruby-on-rails ruby forms ruby-on-rails-4

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 %>

1 个答案:

答案 0 :(得分:1)

Looks like you come from javascript background.

read in all cases needs to be recipeIngredients