Ruby on Rails : 嵌套属性不显示
Ruby on Rails : nested attribute doesn't show up
所以我正在尝试创建一个基本上是食谱的应用程序。
我的主要模型是食谱,它与其他 3 个模型有关系:配料、步骤和烘焙。
对于最后一个,它必须是 has_one/belongs_to 关系。
我的问题是,在我提交表格后,在三个模型中,只有两个第一次(成分和步骤)出现在实际食谱的显示页面上。
这是我的配方控制器代码:
class RecipesController < ApplicationController
def index
@recipes = Recipe.all
end
def show
@recipe = Recipe.includes(:baking).find(params[:id])
end
def new
@recipe = Recipe.new
end
def edit
@recipe = Recipe.find(params[:id])
@baking = @recipe.build_baking
end
def create
@recipe = Recipe.new(recipe_params)
@recipe.save
if @recipe.save
redirect_to recipe_path(@recipe)
else
render 'new'
end
end
def update
@recipe = Recipe.find(params[:id])
@recipe.update(recipe_params)
if @recipe.update(recipe_params)
redirect_to recipe_path(@recipe)
else
render 'edit'
end
end
def destroy
@recipe = Recipe.find(params[:id])
@recipe.destroy
redirect_to root_path
end
private
def recipe_params
params.require(:recipe).permit(:recipe_name, :recipe_notes,
ingredients_attributes: [:id, :ingredient_name, :quantity, :measuring, :other, :optional, :_destroy],
steps_attributes: [:id, :step_description, :step_notes, :_destroy],
bakings_attributes: [:id, :no_baking, :baking_type, :heat, :unit, :duration, :baking_notes, :_destroy])
end
end
这是我的模型:
class Recipe < ApplicationRecord
has_many :ingredients
accepts_nested_attributes_for :ingredients
has_many :steps
accepts_nested_attributes_for :steps
has_one :baking
accepts_nested_attributes_for :baking
end
class Baking < ApplicationRecord
belongs_to :recipe
end
我的表格:
<%= form_for @recipe do |f| %>
<h4>Name</h4>
<%= f.label :recipe_name %> <br>
<%= f.text_field :recipe_name %>
<h4>Ingredients</h4>
<div id="ingredients">
<%= f.fields_for :ingredients do |ingredient| %>
<%= render 'ingredient_fields', :f => ingredient %>
<% end %>
<%= link_to_add_association 'add ingredient', f, :ingredients %>
</div>
<h4>Steps</h4>
<div id="steps">
<%= f.fields_for :steps do |step| %>
<%= render 'step_fields', :f => step %>
<% end %>
<%= link_to_add_association 'add step', f, :steps %>
</div>
<h4>Baking</h4>
<%= f.fields_for :bakings do |baking| %>
<%= f.label :no_baking %> <br>
<%= f.check_box :no_baking %>
<%= f.label :baking_type %> <br>
<%= f.text_field :baking_type %>
<%= f.label :heat %> <br>
<%= f.number_field :heat %>
<%= f.label :unit %> <br>
<%= f.text_field :unit %>
<%= f.label :duration %> <br>
<%= f.number_field :duration %>
<%= f.label :baking_notes %> <br>
<%= f.text_area :baking_notes %>
<% end %>
<%= f.submit 'Share Recipe' %>
<% end %>
最后,这是我的展示页面的样子:
<h1><%= @recipe.recipe_name %></h1>
<h4>Ingredient list</h4>
<% @recipe.ingredients.each do |ingredient| %>
<ul>
<li><strong><%= ingredient.ingredient_name %></strong> <%= ingredient.quantity %> <%= ingredient.measuring %></li>
</ul>
<% end %>
<h4>Steps</h4>
<% @recipe.steps.each do |step| %>
<p><%= step.step_description %></p>
<% if step.step_notes? %>
<small><%= step.step_notes %></small>
<% end %>
<% end %>
<h4>Baking</h4>
<% @recipe.baking do |baking| %>
<p>test</p>
<ul>
<li>Baking type: <%= baking.baking_type %></li>
<li>Baking heat: <%= baking.heat %><%= @recipe.baking.unit %></li>
<li>Cooking Time: <%= baking.duration %> minutes</li>
</ul>
<% if baking.baking_notes? %>
<p><%= baking.baking_notes %></p>
<% end %>
<% end %>
<p><%= @recipe.recipe_notes %></p>
我一直在寻找几种解决方案,但由于我没有得到任何错误来指导我("baking" 部分只是没有出现在显示页面上),我有点迷失在这里。任何提示将不胜感激:)
我是 ruby 的新手,如果问题听起来很愚蠢,我深表歉意。
编辑: 在 recipe_params
中将 bakings_attributes
更改为 baking_attributes
,但烘焙部分仍然没有出现。
这是我提交表单时的日志:
Started POST "/recipes" for 127.0.0.1 at 2018-06-09 13:07:35 +1000
Processing by RecipesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"7dMj/2UOUPgbZrx/e123kd2w1sVZCrfotyHdrrqAM2iNvfO4h0GGPOuYT00NqfTwzuiQtqmrXTEAuMxkY1bnFg==", "recipe"=>{"recipe_name"=>"pizza", "ingredients_attributes"=>{"1528513610918"=>{"ingredient_name"=>"Base", "quantity"=>"", "measuring"=>"", "other"=>"", "optional"=>"0", "_destroy"=>"false"}}, "steps_attributes"=>{"1528513616209"=>{"step_description"=>"Spread the base", "step_notes"=>"", "_destroy"=>"false"}}, "bakings"=>{"no_baking"=>"0", "baking_type"=>"Oven", "heat"=>"200", "unit"=>"C°", "duration"=>"20", "baking_notes"=>""}, "recipe_notes"=>""}, "commit"=>"Share Recipe"}
Unpermitted parameter: :bakings
(0.3ms) BEGIN
SQL (0.5ms) INSERT INTO "recipes" ("recipe_name", "recipe_notes", "created_at", "updated_at") VALUES (, , , ) RETURNING "id" [["recipe_name", "pizza"], ["recipe_notes", ""], ["created_at", "2018-06-09 03:07:35.059515"], ["updated_at", "2018-06-09 03:07:35.059515"]]
SQL (1.3ms) INSERT INTO "ingredients" ("ingredient_name", "measuring", "other", "optional", "created_at", "updated_at", "recipe_id") VALUES (, , , , , , ) RETURNING "id" [["ingredient_name", "Base"], ["measuring", ""], ["other", ""], ["optional", "f"], ["created_at", "2018-06-09 03:07:35.061636"], ["updated_at", "2018-06-09 03:07:35.061636"], ["recipe_id", "26"]]
SQL (0.4ms) INSERT INTO "steps" ("step_description", "step_notes", "created_at", "updated_at", "recipe_id") VALUES (, , , , ) RETURNING "id" [["step_description", "Spread the base"], ["step_notes", ""], ["created_at", "2018-06-09 03:07:35.065734"], ["updated_at", "2018-06-09 03:07:35.065734"], ["recipe_id", "26"]]
(148.7ms) COMMIT
(0.2ms) BEGIN
(0.2ms) COMMIT
Redirected to http://localhost:3000/recipes/26
Completed 302 Found in 165ms (ActiveRecord: 151.5ms)
Started GET "/recipes/26" for 127.0.0.1 at 2018-06-09 13:07:35 +1000
Processing by RecipesController#show as HTML
Parameters: {"id"=>"26"}
Recipe Load (0.3ms) SELECT "recipes".* FROM "recipes" WHERE "recipes"."id" = LIMIT [["id", 26], ["LIMIT", 1]]
Baking Load (0.3ms) SELECT "bakings".* FROM "bakings" WHERE "bakings"."recipe_id" = 26
Rendering recipes/show.html.erb within layouts/application
Ingredient Load (0.2ms) SELECT "ingredients".* FROM "ingredients" WHERE "ingredients"."recipe_id" = [["recipe_id", "26"]]
Step Load (0.2ms) SELECT "steps".* FROM "steps" WHERE "steps"."recipe_id" = [["recipe_id", "26"]]
Rendered recipes/_crud-links.html.erb (1.0ms)
Rendered recipes/show.html.erb within layouts/application (7.9ms)
Completed 200 OK in 41ms (Views: 33.4ms | ActiveRecord: 2.7ms)
似乎导致该问题的错误是:Unpermitted parameter: :bakings
所以我尝试将表格中的行从 <%= f.fields_for :bakings do |f| %>
更改为 <%= f.fields_for :baking do |f| %>
但是烘焙表格没有' t 出现在创建视图中。
知道是什么原因造成的吗?
编辑:
我在我的 def 新方法中添加了 @recipe.build_baking
行,并将烘焙属性列入白名单,如下所示:
private
def recipe_params
params.require(:recipe).permit(:recipe_name,
:recipe_notes,
:no_baking,
:baking_type,
:heat,
:unit,
:duration,
:baking_notes,
ingredients_attributes: [:id, :ingredient_name, :quantity, :measuring, :other, :optional, :_destroy],
steps_attributes: [:id, :step_description, :step_notes, :_destroy])
end
表单仍然无效。
更改您的表单以使用表单生成器进行烘焙而不是使用父表单 - 请注意下面的ff
<%= form_for @recipe do |f| %>
<h4>Name</h4>
<%= f.label :recipe_name %> <br>
<%= f.text_field :recipe_name %>
<h4>Ingredients</h4>
<div id="ingredients">
<%= f.fields_for :ingredients do |ingredient| %>
<%= render 'ingredient_fields', :f => ingredient %>
<% end %>
<%= link_to_add_association 'add ingredient', f, :ingredients %>
</div>
<h4>Steps</h4>
<div id="steps">
<%= f.fields_for :steps do |step| %>
<%= render 'step_fields', :f => step %>
<% end %>
<%= link_to_add_association 'add step', f, :steps %>
</div>
<h4>Baking</h4>
<%= f.fields_for :baking do |ff| %>
<%= ff.label :no_baking %> <br>
<%= ff.check_box :no_baking %>
<%= ff.label :baking_type %> <br>
<%= ff.text_field :baking_type %>
<%= ff.label :heat %> <br>
<%= ff.number_field :heat %>
<%= ff.label :unit %> <br>
<%= ff.text_field :unit %>
<%= ff.label :duration %> <br>
<%= ff.number_field :duration %>
<%= ff.label :baking_notes %> <br>
<%= ff.text_area :baking_notes %>
<% end %>
<%= f.submit 'Share Recipe' %>
<% end %>
将 show
视图的 baking 部分更改为:
<h4>Baking</h4>
<% if baking = @recipe.baking %>
<p>test</p>
<ul>
<li>Baking type: <%= baking.baking_type %></li>
<li>Baking heat: <%= baking.heat %><%= @recipe.baking.unit %></li>
<li>Cooking Time: <%= baking.duration %> minutes</li>
</ul>
<% if baking.baking_notes? %>
<p><%= baking.baking_notes %></p>
<% end %>
<% end %>
在您的控制器中,确保您已列入白名单 baking_attributes
:
def recipe_params
params.require(:recipe).permit(:recipe_name, :recipe_notes,
ingredients_attributes: [:id, :ingredient_name, :quantity, :measuring, :other, :optional, :_destroy],
steps_attributes: [:id, :step_description, :step_notes, :_destroy],
baking_attributes: [:id, :no_baking, :baking_type, :heat, :unit, :duration, :baking_notes, :_destroy])
end
所以我正在尝试创建一个基本上是食谱的应用程序。
我的主要模型是食谱,它与其他 3 个模型有关系:配料、步骤和烘焙。
对于最后一个,它必须是 has_one/belongs_to 关系。
我的问题是,在我提交表格后,在三个模型中,只有两个第一次(成分和步骤)出现在实际食谱的显示页面上。
这是我的配方控制器代码:
class RecipesController < ApplicationController
def index
@recipes = Recipe.all
end
def show
@recipe = Recipe.includes(:baking).find(params[:id])
end
def new
@recipe = Recipe.new
end
def edit
@recipe = Recipe.find(params[:id])
@baking = @recipe.build_baking
end
def create
@recipe = Recipe.new(recipe_params)
@recipe.save
if @recipe.save
redirect_to recipe_path(@recipe)
else
render 'new'
end
end
def update
@recipe = Recipe.find(params[:id])
@recipe.update(recipe_params)
if @recipe.update(recipe_params)
redirect_to recipe_path(@recipe)
else
render 'edit'
end
end
def destroy
@recipe = Recipe.find(params[:id])
@recipe.destroy
redirect_to root_path
end
private
def recipe_params
params.require(:recipe).permit(:recipe_name, :recipe_notes,
ingredients_attributes: [:id, :ingredient_name, :quantity, :measuring, :other, :optional, :_destroy],
steps_attributes: [:id, :step_description, :step_notes, :_destroy],
bakings_attributes: [:id, :no_baking, :baking_type, :heat, :unit, :duration, :baking_notes, :_destroy])
end
end
这是我的模型:
class Recipe < ApplicationRecord
has_many :ingredients
accepts_nested_attributes_for :ingredients
has_many :steps
accepts_nested_attributes_for :steps
has_one :baking
accepts_nested_attributes_for :baking
end
class Baking < ApplicationRecord
belongs_to :recipe
end
我的表格:
<%= form_for @recipe do |f| %>
<h4>Name</h4>
<%= f.label :recipe_name %> <br>
<%= f.text_field :recipe_name %>
<h4>Ingredients</h4>
<div id="ingredients">
<%= f.fields_for :ingredients do |ingredient| %>
<%= render 'ingredient_fields', :f => ingredient %>
<% end %>
<%= link_to_add_association 'add ingredient', f, :ingredients %>
</div>
<h4>Steps</h4>
<div id="steps">
<%= f.fields_for :steps do |step| %>
<%= render 'step_fields', :f => step %>
<% end %>
<%= link_to_add_association 'add step', f, :steps %>
</div>
<h4>Baking</h4>
<%= f.fields_for :bakings do |baking| %>
<%= f.label :no_baking %> <br>
<%= f.check_box :no_baking %>
<%= f.label :baking_type %> <br>
<%= f.text_field :baking_type %>
<%= f.label :heat %> <br>
<%= f.number_field :heat %>
<%= f.label :unit %> <br>
<%= f.text_field :unit %>
<%= f.label :duration %> <br>
<%= f.number_field :duration %>
<%= f.label :baking_notes %> <br>
<%= f.text_area :baking_notes %>
<% end %>
<%= f.submit 'Share Recipe' %>
<% end %>
最后,这是我的展示页面的样子:
<h1><%= @recipe.recipe_name %></h1>
<h4>Ingredient list</h4>
<% @recipe.ingredients.each do |ingredient| %>
<ul>
<li><strong><%= ingredient.ingredient_name %></strong> <%= ingredient.quantity %> <%= ingredient.measuring %></li>
</ul>
<% end %>
<h4>Steps</h4>
<% @recipe.steps.each do |step| %>
<p><%= step.step_description %></p>
<% if step.step_notes? %>
<small><%= step.step_notes %></small>
<% end %>
<% end %>
<h4>Baking</h4>
<% @recipe.baking do |baking| %>
<p>test</p>
<ul>
<li>Baking type: <%= baking.baking_type %></li>
<li>Baking heat: <%= baking.heat %><%= @recipe.baking.unit %></li>
<li>Cooking Time: <%= baking.duration %> minutes</li>
</ul>
<% if baking.baking_notes? %>
<p><%= baking.baking_notes %></p>
<% end %>
<% end %>
<p><%= @recipe.recipe_notes %></p>
我一直在寻找几种解决方案,但由于我没有得到任何错误来指导我("baking" 部分只是没有出现在显示页面上),我有点迷失在这里。任何提示将不胜感激:)
我是 ruby 的新手,如果问题听起来很愚蠢,我深表歉意。
编辑: 在 recipe_params
中将 bakings_attributes
更改为 baking_attributes
,但烘焙部分仍然没有出现。
这是我提交表单时的日志:
Started POST "/recipes" for 127.0.0.1 at 2018-06-09 13:07:35 +1000
Processing by RecipesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"7dMj/2UOUPgbZrx/e123kd2w1sVZCrfotyHdrrqAM2iNvfO4h0GGPOuYT00NqfTwzuiQtqmrXTEAuMxkY1bnFg==", "recipe"=>{"recipe_name"=>"pizza", "ingredients_attributes"=>{"1528513610918"=>{"ingredient_name"=>"Base", "quantity"=>"", "measuring"=>"", "other"=>"", "optional"=>"0", "_destroy"=>"false"}}, "steps_attributes"=>{"1528513616209"=>{"step_description"=>"Spread the base", "step_notes"=>"", "_destroy"=>"false"}}, "bakings"=>{"no_baking"=>"0", "baking_type"=>"Oven", "heat"=>"200", "unit"=>"C°", "duration"=>"20", "baking_notes"=>""}, "recipe_notes"=>""}, "commit"=>"Share Recipe"}
Unpermitted parameter: :bakings
(0.3ms) BEGIN
SQL (0.5ms) INSERT INTO "recipes" ("recipe_name", "recipe_notes", "created_at", "updated_at") VALUES (, , , ) RETURNING "id" [["recipe_name", "pizza"], ["recipe_notes", ""], ["created_at", "2018-06-09 03:07:35.059515"], ["updated_at", "2018-06-09 03:07:35.059515"]]
SQL (1.3ms) INSERT INTO "ingredients" ("ingredient_name", "measuring", "other", "optional", "created_at", "updated_at", "recipe_id") VALUES (, , , , , , ) RETURNING "id" [["ingredient_name", "Base"], ["measuring", ""], ["other", ""], ["optional", "f"], ["created_at", "2018-06-09 03:07:35.061636"], ["updated_at", "2018-06-09 03:07:35.061636"], ["recipe_id", "26"]]
SQL (0.4ms) INSERT INTO "steps" ("step_description", "step_notes", "created_at", "updated_at", "recipe_id") VALUES (, , , , ) RETURNING "id" [["step_description", "Spread the base"], ["step_notes", ""], ["created_at", "2018-06-09 03:07:35.065734"], ["updated_at", "2018-06-09 03:07:35.065734"], ["recipe_id", "26"]]
(148.7ms) COMMIT
(0.2ms) BEGIN
(0.2ms) COMMIT
Redirected to http://localhost:3000/recipes/26
Completed 302 Found in 165ms (ActiveRecord: 151.5ms)
Started GET "/recipes/26" for 127.0.0.1 at 2018-06-09 13:07:35 +1000
Processing by RecipesController#show as HTML
Parameters: {"id"=>"26"}
Recipe Load (0.3ms) SELECT "recipes".* FROM "recipes" WHERE "recipes"."id" = LIMIT [["id", 26], ["LIMIT", 1]]
Baking Load (0.3ms) SELECT "bakings".* FROM "bakings" WHERE "bakings"."recipe_id" = 26
Rendering recipes/show.html.erb within layouts/application
Ingredient Load (0.2ms) SELECT "ingredients".* FROM "ingredients" WHERE "ingredients"."recipe_id" = [["recipe_id", "26"]]
Step Load (0.2ms) SELECT "steps".* FROM "steps" WHERE "steps"."recipe_id" = [["recipe_id", "26"]]
Rendered recipes/_crud-links.html.erb (1.0ms)
Rendered recipes/show.html.erb within layouts/application (7.9ms)
Completed 200 OK in 41ms (Views: 33.4ms | ActiveRecord: 2.7ms)
似乎导致该问题的错误是:Unpermitted parameter: :bakings
所以我尝试将表格中的行从 <%= f.fields_for :bakings do |f| %>
更改为 <%= f.fields_for :baking do |f| %>
但是烘焙表格没有' t 出现在创建视图中。
知道是什么原因造成的吗?
编辑:
我在我的 def 新方法中添加了 @recipe.build_baking
行,并将烘焙属性列入白名单,如下所示:
private
def recipe_params
params.require(:recipe).permit(:recipe_name,
:recipe_notes,
:no_baking,
:baking_type,
:heat,
:unit,
:duration,
:baking_notes,
ingredients_attributes: [:id, :ingredient_name, :quantity, :measuring, :other, :optional, :_destroy],
steps_attributes: [:id, :step_description, :step_notes, :_destroy])
end
表单仍然无效。
更改您的表单以使用表单生成器进行烘焙而不是使用父表单 - 请注意下面的ff
<%= form_for @recipe do |f| %>
<h4>Name</h4>
<%= f.label :recipe_name %> <br>
<%= f.text_field :recipe_name %>
<h4>Ingredients</h4>
<div id="ingredients">
<%= f.fields_for :ingredients do |ingredient| %>
<%= render 'ingredient_fields', :f => ingredient %>
<% end %>
<%= link_to_add_association 'add ingredient', f, :ingredients %>
</div>
<h4>Steps</h4>
<div id="steps">
<%= f.fields_for :steps do |step| %>
<%= render 'step_fields', :f => step %>
<% end %>
<%= link_to_add_association 'add step', f, :steps %>
</div>
<h4>Baking</h4>
<%= f.fields_for :baking do |ff| %>
<%= ff.label :no_baking %> <br>
<%= ff.check_box :no_baking %>
<%= ff.label :baking_type %> <br>
<%= ff.text_field :baking_type %>
<%= ff.label :heat %> <br>
<%= ff.number_field :heat %>
<%= ff.label :unit %> <br>
<%= ff.text_field :unit %>
<%= ff.label :duration %> <br>
<%= ff.number_field :duration %>
<%= ff.label :baking_notes %> <br>
<%= ff.text_area :baking_notes %>
<% end %>
<%= f.submit 'Share Recipe' %>
<% end %>
将 show
视图的 baking 部分更改为:
<h4>Baking</h4>
<% if baking = @recipe.baking %>
<p>test</p>
<ul>
<li>Baking type: <%= baking.baking_type %></li>
<li>Baking heat: <%= baking.heat %><%= @recipe.baking.unit %></li>
<li>Cooking Time: <%= baking.duration %> minutes</li>
</ul>
<% if baking.baking_notes? %>
<p><%= baking.baking_notes %></p>
<% end %>
<% end %>
在您的控制器中,确保您已列入白名单 baking_attributes
:
def recipe_params
params.require(:recipe).permit(:recipe_name, :recipe_notes,
ingredients_attributes: [:id, :ingredient_name, :quantity, :measuring, :other, :optional, :_destroy],
steps_attributes: [:id, :step_description, :step_notes, :_destroy],
baking_attributes: [:id, :no_baking, :baking_type, :heat, :unit, :duration, :baking_notes, :_destroy])
end