RecipesとIngredientsの間に多対多の関係があります。レシピに材料を追加できるフォームを作成しようとしています。
(この質問のバリエーションが繰り返し尋ねられました。私はこれに何時間も費やしましたが、根本的に混乱してaccepts_nested_attributes_for
います。)
以下のすべてのコードに怯える前に、これが本当に基本的な質問であることを理解していただければ幸いです。ここに怖くない詳細があります...
エラー
レシピを作成するフォームを表示すると、「uninitialized constant Recipe::IngredientsRecipe」というエラーが表示され、フォームの一部の行を指しています。
18: <%= f.fields_for :ingredients do |i| %>
この行を変更して「成分」を単数形にする場合
<%= f.fields_for :ingredient do |i| %>
フォームが表示されますが、保存すると大量割り当てエラーが発生しますCan't mass-assign protected attributes: ingredient
。
モデル (3 つのファイルで、それに応じて名前が付けられます)
class Recipe < ActiveRecord::Base
attr_accessible :name, :ingredient_id
has_many :ingredients, :through => :ingredients_recipes
has_many :ingredients_recipes
accepts_nested_attributes_for :ingredients
accepts_nested_attributes_for :ingredients_recipes
end
class Ingredient < ActiveRecord::Base
attr_accessible :name, :recipe_id
has_many :ingredients_recipes
has_many :recipes, :through => :ingredients_recipes
accepts_nested_attributes_for :recipes
accepts_nested_attributes_for :ingredients_recipes
end
class IngredientsRecipes < ActiveRecord::Base
belongs_to :ingredient
belongs_to :recipe
attr_accessible :ingredient_id, :recipe_id
accepts_nested_attributes_for :recipes
accepts_nested_attributes_for :ingredients
end
コントローラー
によって生成された RESTful リソースとしてrails generate scaffold
そして、「レシピ」の複数形は不規則なので、inflections.rb
ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 'recipe', 'recipes'
end
見る ( recipes/_form.html.erb
)
<%= form_for(@recipe) do |f| %>
<div class="field">
<%= f.label :name, "Recipe" %><br />
<%= f.text_field :name %>
</div>
<%= f.fields_for :ingredients do |i| %>
<div class="field">
<%= i.label :name, "Ingredient" %><br />
<%= i.collection_select :ingredient_id, Ingredient.all, :id, :name %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
環境
- レール 3.2.9
- ルビー1.9.3
いくつか試したこと
ビューを変更するとf.fields_for :ingredient
、フォームが読み込まれます (Recipe::IngredientRecipe
正しく検出されますが、保存すると、上記のように大量割り当てエラーが発生します。ログは次のとおりです)。
Started POST "/recipes" for 127.0.0.1 at 2012-11-20 16:50:37 -0500
Processing by RecipesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"/fMS6ua0atk7qcXwGy7NHQtuOnJqDzoW5P3uN9oHWT4=", "recipe"=>{"name"=>"Stewed Tomatoes", "ingredient"=>{"ingredient_id"=>"1"}}, "commit"=>"Create Recipe"}
Completed 500 Internal Server Error in 2ms
ActiveModel::MassAssignmentSecurity::Error (Can't mass-assign protected attributes: ingredient):
app/controllers/recipes_controller.rb:43:in `new'
app/controllers/recipes_controller.rb:43:in `create'
コントローラーの失敗した行は単純です
@recipe = Recipe.new(params[:recipe])
したがって、ネストされた属性を含む、渡されるパラメーターは、何らかの形で正しくありません。しかし、私は、修正して別のものを壊す多くのバリアントを試しました。私は何を理解できていないのですか?