Reputation: 554
Update: I had two issues in here - the one listed in the console had not matched the title I posted. The issue with actionView::Template::error was in fact caused by the lack of pluralization - I gave answer for it to the most complete answer below - thank you!
Original Question:
I'm working with cocoon gemfile & following the ERB style of it without haml/slim. I have my github here - The branch I'm working on is "cmodel" -Link. I got one of the errors taken care of myself - but this last one is just elusive - oddly too - I lost the field that normally shows the ingredient with the quantity - back on to the point...
My question is ... since when I search my repo on github for "ingredient_attributes" & see it only in my controller parameter's ... where is the error coming from & what would fix it?
"Unpermitted parameter: ingredient_attributes"
or
"Unpermitted parameter: ingredients" is coming from ... I managed to get this mostly working - this is the last element and I've been over a ton of files and stated pluralization etc, along with trying 3 or 4 formats for the accept_parameters_for & then the ingredient_attributes.
My console output for the current error:
Started GET "/recipes/1/edit" for 68.54.21.200 at 2015-12-21 02:53:27 +0000
Cannot render console from 68.54.21.200! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by RecipesController#edit as HTML
Parameters: {"id"=>"1"}
Recipe Load (0.2ms) SELECT "recipes".* FROM "recipes" WHERE "recipes"."id" = ? LIMIT 1 [["id", 1]]
CACHE (0.0ms) SELECT "recipes".* FROM "recipes" WHERE "recipes"."id" = ? LIMIT 1 [["id", "1"]]
Rendered recipes/_form.html.erb (8.2ms)
Rendered recipes/edit.html.erb within layouts/application (9.8ms)
Completed 500 Internal Server Error in 16ms (ActiveRecord: 0.3ms)
ActionView::Template::Error (No association found for name `ingredients'. Has it been defined yet?):
30:
31: <fieldset id="recipe-ingredients">
32: <ol>
33: <%= f.fields_for :quantities do |quantity| %>
34: <%= render 'quantity_fields', f: quantity %>
35: <% end %>
36: </ol>
app/models/quantity.rb:6:in `<class:Quantity>'
app/models/quantity.rb:1:in `<top (required)>'
app/views/recipes/_form.html.erb:33:in `block in _app_views_recipes__form_html_erb___1490943344300843366_36721460'
app/views/recipes/_form.html.erb:1:in `_app_views_recipes__form_html_erb___1490943344300843366_36721460'
app/views/recipes/edit.html.erb:3:in `_app_views_recipes_edit_html_erb___3608590124593016081_36957880'
Rendered /usr/local/rvm/gems/ruby-2.2.1/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_source.erb (20.7ms)
Rendered /usr/local/rvm/gems/ruby-2.2.1/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (5.1ms)
Rendered /usr/local/rvm/gems/ruby-2.2.1/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (3.6ms)
Rendered /usr/local/rvm/gems/ruby-2.2.1/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb within rescues/layout (99.4ms)
Setup
Models:
class Recipe < ActiveRecord::Base
has_many :quantities
has_many :ingredient,
:through => :quantities
accepts_nested_attributes_for :quantities,
:allow_destroy => true
accepts_nested_attributes_for :ingredient
end
class Quantity < ActiveRecord::Base
belongs_to :recipe
belongs_to :ingredient
accepts_nested_attributes_for :ingredient
end
class Ingredient < ActiveRecord::Base
has_many :quantities
has_many :recipes, through: :quantities
accepts_nested_attributes_for :quantities
end
Controller:
class RecipesController < ApplicationController
before_action :set_recipe, only: [:show, :edit, :update, :destroy]
# GET /recipes/1/edit
def edit
@recipe = Recipe.find(params[:id])
end
# POST /recipes
# POST /recipes.json
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
# PATCH/PUT /recipes/1
# PATCH/PUT /recipes/1.json
def update
respond_to do |format|
if @recipe.update(recipe_params)
format.html { redirect_to @recipe, notice: 'Recipe was successfully updated.' }
format.json { render :show, status: :ok, location: @recipe }
else
format.html { render :edit }
format.json { render json: @recipe.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_recipe
@recipe = Recipe.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def recipe_params
#seems to work, but getting errors saving
params.require(:recipe).permit(:title, :description, :instruction,
quantities_attributes: [:id, :amount, :ingredient, :_destroy],
ingredient_attributes: [:id, :name, :_destroy],
recipe_attributes: [:title, :description, :_destroy])
end
end
Here's the views ... portion from the github I linked above ...
edit.html.erb
<h1>Editing Recipe</h1>
<%= render 'form' %>
<%= link_to 'Show', @recipe %> |
<%= link_to 'Back', recipes_path %>
_form.html.erb
<%= form_for @recipe, html: {class: "form-horizontal"} 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 %>
<fieldset id="recipe-meta">
<ol>
<li class="control-group">
<%= f.label :title, "Recipe Name", class: "control-label" %>
<div class="controls"><%= f.text_field :title %></div>
</li>
<li class="control-group">
<%= f.label :description, "A brief description of this recipe", class: "control-label" %>
<div class="controls"><%= f.text_area :description, rows: 5 %></div>
</li>
<li class="control-group">
<%= f.label :instruction, "Instructions for this recipe", class: "control-label" %>
<div class="controls"><%= f.text_area :instruction, rows: 10 %></div>
</li>
</ol>
</fieldset>
<fieldset id="recipe-ingredients">
<ol>
<%= f.fields_for :quantities do |quantity| %>
<%= render 'quantity_fields', f: quantity %>
<% end %>
</ol>
<%= link_to_add_association 'add ingredient', f, :quantities, 'data-association-insertion-node' => "#recipe-ingredients ol", 'data-association-insertion-method' => "append", :wrap_object => Proc.new {|quantity| quantity.build_ingredient; quantity } %>
</fieldset>
<%= f.submit %>
</div>
<% end %>
_quantity_fields.html.erb
<li class="control-group nested-fields">
<div class="controls">
<%= f.label :amount, "Amount:" %>
<%= f.text_field :amount %>
<%= f.fields_for :ingredient do |quantity_ingredient| %>
<%= quantity_ingredient.text_field :name %>
<% end %>
<%= link_to_remove_association "remove", f %>
</div>
</li>
Upvotes: 0
Views: 125
Reputation: 76774
As an addition to Praveen George
's answer, you can debug Rails relatively simply if you follow what it says on screen (most of the time):
No association found for name `ingredients'. Has it been defined yet?
This basically means that you don't have the ingredients
association defined in the model you're calling.
As pointed out by Praveen
, your problem resides in the Recipe
model. You have to call the association by its pluralized name:
#app/models/recipe.rb
class Recipe < ActiveRecord::Base
has_many :ingredients
accepts_nested_attributes_for :ingredients
end
Upvotes: 2
Reputation: 9715
There is an error in declaring association class Recipe with has_many relation. try changing the relation to the following in your Recipe model
has_many :ingredients
Upvotes: 2