2

我有 3 个嵌套模型:

class Recipe < ActiveRecord::Base
  has_many :recipe_ingredients
  has_many :ingredients, :through => :recipe_ingredients
  accepts_nested_attributes_for :ingredients
  accepts_nested_attributes_for :recipe_ingredients, :allow_destroy => true

  attr_accessible :description, :name, :preparation, :recipe_ingredients_attributes, :ingredients_attributes
  validates_presence_of :name, :description, :preparation
end

class RecipeIngredient < ActiveRecord::Base
  belongs_to :recipe, :foreign_key => "recipe_id"
  belongs_to :ingredient, :foreign_key => "ingredient_id"
  accepts_nested_attributes_for :ingredient
  delegate :name, :to => :ingredient, :allow_nil => true

  attr_accessible :ingredient_id, :quantity, :recipe_id, :ingredient_attributes
end

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

  attr_accessible :name
end

这是我的食谱控制器:

#<snip>
def new
  @recipe = Recipe.new

  respond_to do |format|
    format.html # new.html.erb
    format.json { render json: @recipe }
  end
end

def create
  @recipe = Recipe.new(params[:recipe])

  respond_to do |format|
    if @recipe.save
      format.html { redirect_to @recipe, notice: 'Het recept werd aangemaakt.' }
      format.json { render json: @recipe, status: :created, location: @recipe }
    else
      format.html { render action: "new" }
      format.json { render json: @recipe.errors, status: :unprocessable_entity }
    end
  end
end
#</snip>

这就是我的表单的样子(使用 simple_forms 和 nested_forms gems):

= simple_nested_form_for @recipe, :html => { :class => 'form-horizontal' } do |f|
  = f.input :name, :label => "Naam"
  = f.input :description, :input_html => { :class => "span6" }, :label => "Beschrijving"
  = f.input :preparation, :input_html => { :class => "span6" }, :label => "Bereiding"

  = f.simple_fields_for :recipe_ingredients do |ri|
    = ri.input :quantity, :label => "#"
    = ri.input :name, :label => "Ingredient"
    = ri.link_to_remove "ingredient verwijderen"
  %p
    = f.link_to_add "Voeg ingredient toe", :recipe_ingredients

  .form-actions
    = f.submit "Update recept", :class => 'btn btn-primary'
    = link_to t('.cancel', :default => "Annuleer"), recipes_path, :class => 'btn'

每当我保存食谱时,它都会给我:ActiveModel::MassAssignmentSecurity::Error in RecipesController#create Can't mass-assign protected attributes: name

这是我的堆栈跟踪:

Started POST "/recipes" for 127.0.0.1 at 2012-12-15 19:14:38 +0100
Processing by RecipesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"72F9E5Cim3SFlFabViy8p4eF4el+RGtdlPmkuaoBU90=", "recipe"=>{"name"=>"tets", "description"=>"egwrb", "preparation"=>"gwrv", "recipe_ingredients_attributes"=>{"1355595249889"=>{"quantity"=>"21", "name"=>"grsd", "_destroy"=>"false"}}}, "commit"=>"Update recept"}
  User Load (0.4ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
Completed 500 Internal Server Error in 2ms

ActiveModel::MassAssignmentSecurity::Error (Can't mass-assign protected attributes: name):
  app/controllers/recipes_controller.rb:54:in `new'
  app/controllers/recipes_controller.rb:54:in `create'

我试过玩单数/复数,但没有运气。我不知道我做错了什么。:ingredient_attributes 应该可以访问,但似乎不是?

亲切的问候,史蒂文

4

2 回答 2

0

实际上,我认为您的观点只是有一个小错字:

= f.simple_fields_for :ingredient do |i|

应该

= ri.simple_fields_for :ingredient do |i|

我注意到 params 哈希在顶层有成分,当它应该嵌套在recipe_ingredients_attributes. (您可能还需要设置accepts_nested_attributes_foron RecipeIngredient

于 2012-12-15T17:53:45.900 回答
0

您必须创建一组额外的嵌套字段。在ri您需要添加的块内

- ri.simple_fields_for :ingredient do |i|
  = i.input :name

通过这样做,您正确设置了名称ingredient而不是recipe_ingredient.

于 2012-12-15T18:33:07.140 回答