I'm writing an Recipe app in Rails. Now I'm stuck in this error. I spent a week to find the solution for this problem.
Update model Here is my model:
class Recipe < ActiveRecord::Base
has_many :ingredient_recipes
has_many :ingredients, :through => :ingredient_recipes
accepts_nested_attributes_for :ingredient_recipes
end
class Ingredient < ActiveRecord::Base
has_many :ingredient_recipes
has_many :recipes, :through => :ingredient_recipes
end
class IngredientRecipe < ActiveRecord::Base
belongs_to :recipe
belongs_to :ingredient
end
IngredientRecipe is a join model that is used to store the value of recipe and ingredient.
In 'New' action, I want to create new recipe along with the Ingredient for that recipe, and specify the quantity (quantity is an additional attribute in the join table IngredientRecipe) for that ingredient.
When I click submit, it just creates a new Recipe, it doesn't create a record in the Join table.
Here is my error:
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"AbnDeDLDWq3lvy4pozvXStVy7NeOIUuv1DU1U2/2EJ6n
/jM6E1669hyB90733XTY9DGAvc2hbbDmbL6NwhqCUg==",
"recipe"=>{"rec_name"=>"j", "rec_description"=>"k",
"ingredient_recipe"=>{"ingredient"=>{"id"=>"1"},
"quantity"=>"1"}}, "commit"=>"Create Recipe"}
Unpermitted parameter: ingredient_recipe
(0.1ms) BEGIN
SQL (0.2ms) INSERT INTO `recipes` (`rec_name`, `rec_description`,
`created_at`, `updated_at`) VALUES ('j', 'k', '2015-06-25 21:48:09', '2015-06-25 21:48:09')
(1.1ms) COMMIT
Redirected to http://localhost:3000/recipes/50
Completed 302 Found in 6ms (ActiveRecord: 1.4ms)
Updated controller My recipe controller: Updated controller
def new
@recipe = Recipe.new
3.times { @recipe.ingredient_recipes.build.build_ingredient }
end
def create
@recipe = Recipe.new(recipe_params)
respond_to do |format|
if @recipe.save
format.html { redirect_to @recipe, notice: 'Recipe was successfully created.' }
format.json { render :show, status: :created, location: @recipe }
else
format.html { render :new }
format.json { render json: @recipe.errors, status: :unprocessable_entity }
end
end
end
My recipe view form:
<%= form_for(@recipe) do |f| %>
<% if @recipe.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@recipe.errors.count, "error") %> prohibited this recipe from being saved:</h2>
<ul>
<% @recipe.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :rec_name %><br>
<%= f.text_field :rec_name %>
</div>
<div class="field">
<%= f.label :rec_description %><br>
<%= f.text_area :rec_description %>
</div>
<table>
<thead>
<tr>
<th>Ingredients</th>
<th>Unit</th>
<th>Quantity</th>
<th>New Quantity</th>
</tr>
</thead>
<tbody>
<%= f.fields_for :ingredient_recipes do |fi| %>
<%= fi.fields_for do |i| %>
<tr>
<td> <%=i.collection_select(:ingredient_id, Ingredient.all, :id, :ing_name) %></td>
<% end %>
<td> <%=fi.text_field :quantity %></td>
</tr>
<% end %>
</tbody>
</table>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
No errors after I updated but here is the parameters what I get when I submit create action: Parameters: {"utf8"=>"✓", "authenticity_token"=>"NCT4NgS6ZvbqpcS4+CsoYI4pJurYzwsCyj5U6k3MTwSFqDpdLMX+XVFIpAP/pXD3ZDNr6T6mIOf58gUk6SEqOQ==", "recipe"=>{"rec_name"=>"s", "rec_description"=>"s", "ingredient_recipes_attributes"=>{"0"=>{"ingredient_id"=>"2", "quantity"=>"1"}, "1"=>{"ingredient_id"=>"1", "quantity"=>"1"}, "2"=>{"ingredient_id"=>"3", "quantity"=>"1"}}}, "commit"=>"Create Recipe"} (0.6ms) BEGIN SQL (4.6ms) INSERT INTO recipes
( created_at
, updated_at
) VALUES ('2015-07-01 00:37:28', '2015-07-01 00:37:28') (2.1ms) COMMIT Redirected to http://localhost:3000/recipes/65 Completed 302 Found in 24ms (ActiveRecord: 7.3ms)
Started GET "/recipes/65" for 127.0.0.1 at 2015-06-30 17:37:28 -0700 Processing by RecipesController#show as HTML Parameters: {"id"=>"65"} Recipe Load (4.7ms) SELECT recipes
.* FROM recipes
WHERE recipes
. id
= 65 LIMIT 1 Rendered recipes/show.html.erb within layouts/application (0.7ms) Completed 200 OK in 136ms (Views: 126.4ms | ActiveRecord: 4.7ms)
It seems everything is on the right way but I don't know why after render show action It doesn't show the attributes of the recipe I just added, and It also didn't create the record in the join table.
Please help me! Thanks so much
class Ingredient < ActiveRecord::Base
has_many :ingredient_recipes, inverse_of: :ingredient_recipes, autosave: true
has_many :recipes, :through => :ingredient_recipes
The following line is not correct. An inverse relationship to itself is not valid:
has_many :ingredient_recipes, inverse_of: :ingredient_recipes, autosave: true
This is why you're getting the error:
Unpermitted parameter: ingredient_recipe
class IngredientRecipe < ActiveRecord::Base
belongs_to :recipe, :inverse_of ingredient_recipes
belongs_to :ingredient
accepts_nested_attributes_for :ingredient
end
You must first create the parent record successfully before adding the "belongs to" child. Your autosave a parameter supposedly does this action, but it is not working for some reason, which you have to debug. To do this I suggest that you explicitly create an action on the child tables after you create your parent recipe record.
Once you get the parent and child records creating properly with explicit calls, then put the autosave back in the model, rollback the explicit creates and see if the parent save invokes the child save. I always use explicit saves because I want to control the process.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.