Rails 4 个嵌套属性 simple_fields_for 一个保存到数据库,一个不保存到数据库
Rails 4 Nested Attributes with simple_fields_for One Saves and One Doesn't Save to Database
研究:[Rails 4 个具有 fields_for 的嵌套属性不保存到数据库] [Rails 4 - 具有 Cocoon 的嵌套属性 gem][Rails 4.1 Nested Attributes and Fields For Getting Unpermitted Parameters and Not Saving]2
我的具体问题是:
我有两个嵌套表单:Ingredients 和 Directions
成分保存但说明不保存。它不会抛出错误,日志也没有关于是否存在问题的线索。
首先,让我们解决最常见的问题:强参数的属性参数命名不正确。我的是正确的复数。
class RecipesController < ApplicationController
def recipe_params
params.require(:recipe).permit(:title, :image, directions_attributes: [:id, :name, :_destroy], ingredients_attributes: [:id, :name, :_destroy])
end
我的模型也设置正确
class Recipe < ActiveRecord::Base
has_many :ingredients
has_many :directions
belongs_to :user
accepts_nested_attributes_for :ingredients, reject_if: :all_blank, allow_destroy: true
accepts_nested_attributes_for :directions, reject_if: :all_blank, allow_destroy: true
validates :title, presence: true
mount_uploader :image, ImageUploader
end
#_form.html.haml
= simple_form_for @recipe, html: { multipart: true } do |f|
- if @recipe.errors.any?
#errors
%p
= @recipe.error.count
Prevented this recipe from saving
%ul
%li= msg
.panel-body
= f.input :title, label: "Name", input_html: { class: 'form-control' }
= f.input :image, label: "Picture",input_html: { class: 'form-control' }
.row
.col-md-6
%h3 Ingredients
#ingredients
= f.simple_fields_for :ingredients do |ingredient|
= render 'ingredient_fields', f: ingredient
.links
= link_to_add_association 'Add Ingredient', f, :ingredients, class: "btn btn-default add-button"
.col-md-6
%h3 Directions
#directions
= f.simple_fields_for :directions do |direction|
= render 'direction_fields', f: direction
.links
= link_to_add_association 'Add Step', f, :directions, class: "btn btn-default add-button"
= f.button :submit, class: "btn btn-primary"
这是我对成分和方向的偏爱
_ingredient_fields.html.haml
.form-inline.clearfix
.nested-fields
= f.input :name, input_html: { class: "form-input form-control"}
= link_to_remove_association 'Remove', f, class: "form-button btn btn-default"
_direction_fields.html.haml
.form-inline.clearfix
.nested-fields
= f.input :name, input_html: { class: "form-input form-control"}
= link_to_remove_association 'Remove', f, class: "form-button btn btn-default"
好的,有趣的是,我的应用程序没有抛出任何错误。名称、图像和成分会保存,但说明不会。
这是日志
于 2016 年 2 月 12 日开始 POST ::1 的“/食谱”19:00:07 -0800
RecipesController 处理#create as HTML
参数:{"utf8"=>"✓", "authenticity_token"=>"YEXiv10mHkfdLPRFGHFGNJX2szJQVXK7gezeakEFbe+57afx6Ih1UjRS6tJNftDLsMI5NS1W84pf2sRhQi0J8g==", "recipe"=>{"title"=>"Honey Apple Chicken", "image"=>#, @original_filename="Honey-Mustard-Chicken-and-Apples.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"recipe[image]\"; filename= \"Honey-Mustard-Chicken-and-Apples.jpg\"\r\nContent-Type: image/jpeg\r\n">, "ingredients_attributes"=>{"1455332308170"=>{"name"=>"Chicken Thighs", "_destroy"=>"false"}, "1455332308175"=>{"name"=>"Honey", "_destroy"=>"false"}}, "directions_attributes"=>{"1455332325877"=>{"step"=>"Brown Chicken with skin on.", "_destroy"=>"false"}, "1455332325880"=>{"step"=>"Add apples", "_destroy"=>"false"}}}, "commit"=>"Create Recipe"}
用户负载 (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ?按 "users"."id" 升序限制 1 [["id", 1]]
不允许的参数:步骤
不允许的参数:step
(0.1ms) 开始交易
配方存在(0.2 毫秒)SELECT 1 作为一个 FROM "recipes" WHERE "recipes"."image" = ?限制 1 [["image", "1455332407-84040-0233/Honey-Mustard-Chicken-and-Apples.jpg"]]
SQL(0.4 毫秒)插入 "recipes"("title"、"image"、"user_id"、"created_at"、"updated_at")值(? , ?, ?, ?, ?) [["title", "Honey Apple Chicken"], ["image", "1455332407-84040-0233/Honey-Mustard-Chicken-and-Apples.jpg"], ["user_id", 1], ["created_at", "2016-02-13 03:00:07.756946"], ["updated_at", "2016-02-13 03:00:07.756946"]]
SQL(0.2 毫秒)插入 "ingredients"("name"、"recipe_id"、"created_at"、"updated_at")值(?、?、?、? ) [["name", "Chicken Thighs"], ["recipe_id", 1], ["created_at", "2016-02-13 03:00:07.758440"], [ "updated_at", "2016-02-13 03:00:07.758440"]]
SQL(0.1 毫秒)插入 "ingredients"("name"、"recipe_id"、"created_at"、"updated_at")值(?、?、?、? ) [["name", "Honey"], ["recipe_id", 1], ["created_at", "2016-02-13 03:00:07.759655"], [ "updated_at", "2016-02-13 03:00:07.759655"]]
(2.5ms) 提交事务
重定向至 http://localhost:3000/recipes/1
完成 302 在 1499 毫秒内找到(ActiveRecord:3.5 毫秒)
于 2016 年 2 月 12 日开始为 ::1 获取“/recipes/1”19:00:09-0800
RecipesController 处理#show as HTML
参数:{"id"=>"1"}
配方加载 (0.3ms) SELECT "recipes".* FROM "recipes" WHERE "recipes"."id" = ?限制 1 [["id", 1]]
用户负载 (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ?限制 1 [["id", 1]]
成分负载 (0.3ms) SELECT "ingredients".* FROM "ingredients" WHERE "ingredients"."recipe_id" = ? [["recipe_id", 1]]
方向负载 (0.1ms) SELECT "directions".* FROM "directions" WHERE "directions"."recipe_id" = ? [["recipe_id", 1]]
用户负载 (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ?按 "users"."id" 升序限制 1 [["id", 1]]
在 layouts/application(9.2 毫秒)内呈现 recipes/show.html.haml
在 47 毫秒内完成 200 OK(视图:41.2 毫秒 | ActiveRecord:1.0 毫秒)
我不明白 Karl 对他自己的问题的回答:Rails 4.1 Nested Attributes and Fields For Getting Unpermitted Parameters and Not Saving
如果你能看到任何东西,你就是 Macgyver!
您可以更改:
params.require(:recipe).permit(:title, :image, directions_attributes: [:id, :name, :_destroy], ingredients_attributes: [:id, :name, :_destroy])
为
params.require(:recipe).permit(:title, :image, directions_attributes: [:id, :name, :step, :_destroy], ingredients_attributes: [:id, :name, :_destroy])
您尝试在不允许的情况下发送 "step",如果您在方向模型中对 setp 列进行了 not_blank 验证,则不会保存。
研究:[Rails 4 个具有 fields_for 的嵌套属性不保存到数据库] [Rails 4 - 具有 Cocoon 的嵌套属性 gem]
我的具体问题是:
我有两个嵌套表单:Ingredients 和 Directions
成分保存但说明不保存。它不会抛出错误,日志也没有关于是否存在问题的线索。
首先,让我们解决最常见的问题:强参数的属性参数命名不正确。我的是正确的复数。
class RecipesController < ApplicationController
def recipe_params
params.require(:recipe).permit(:title, :image, directions_attributes: [:id, :name, :_destroy], ingredients_attributes: [:id, :name, :_destroy])
end
我的模型也设置正确
class Recipe < ActiveRecord::Base
has_many :ingredients
has_many :directions
belongs_to :user
accepts_nested_attributes_for :ingredients, reject_if: :all_blank, allow_destroy: true
accepts_nested_attributes_for :directions, reject_if: :all_blank, allow_destroy: true
validates :title, presence: true
mount_uploader :image, ImageUploader
end
#_form.html.haml
= simple_form_for @recipe, html: { multipart: true } do |f|
- if @recipe.errors.any?
#errors
%p
= @recipe.error.count
Prevented this recipe from saving
%ul
%li= msg
.panel-body
= f.input :title, label: "Name", input_html: { class: 'form-control' }
= f.input :image, label: "Picture",input_html: { class: 'form-control' }
.row
.col-md-6
%h3 Ingredients
#ingredients
= f.simple_fields_for :ingredients do |ingredient|
= render 'ingredient_fields', f: ingredient
.links
= link_to_add_association 'Add Ingredient', f, :ingredients, class: "btn btn-default add-button"
.col-md-6
%h3 Directions
#directions
= f.simple_fields_for :directions do |direction|
= render 'direction_fields', f: direction
.links
= link_to_add_association 'Add Step', f, :directions, class: "btn btn-default add-button"
= f.button :submit, class: "btn btn-primary"
这是我对成分和方向的偏爱
_ingredient_fields.html.haml
.form-inline.clearfix
.nested-fields
= f.input :name, input_html: { class: "form-input form-control"}
= link_to_remove_association 'Remove', f, class: "form-button btn btn-default"
_direction_fields.html.haml
.form-inline.clearfix
.nested-fields
= f.input :name, input_html: { class: "form-input form-control"}
= link_to_remove_association 'Remove', f, class: "form-button btn btn-default"
好的,有趣的是,我的应用程序没有抛出任何错误。名称、图像和成分会保存,但说明不会。
这是日志
于 2016 年 2 月 12 日开始 POST ::1 的“/食谱”19:00:07 -0800 RecipesController 处理#create as HTML 参数:{"utf8"=>"✓", "authenticity_token"=>"YEXiv10mHkfdLPRFGHFGNJX2szJQVXK7gezeakEFbe+57afx6Ih1UjRS6tJNftDLsMI5NS1W84pf2sRhQi0J8g==", "recipe"=>{"title"=>"Honey Apple Chicken", "image"=>#, @original_filename="Honey-Mustard-Chicken-and-Apples.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"recipe[image]\"; filename= \"Honey-Mustard-Chicken-and-Apples.jpg\"\r\nContent-Type: image/jpeg\r\n">, "ingredients_attributes"=>{"1455332308170"=>{"name"=>"Chicken Thighs", "_destroy"=>"false"}, "1455332308175"=>{"name"=>"Honey", "_destroy"=>"false"}}, "directions_attributes"=>{"1455332325877"=>{"step"=>"Brown Chicken with skin on.", "_destroy"=>"false"}, "1455332325880"=>{"step"=>"Add apples", "_destroy"=>"false"}}}, "commit"=>"Create Recipe"} 用户负载 (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ?按 "users"."id" 升序限制 1 [["id", 1]] 不允许的参数:步骤 不允许的参数:step (0.1ms) 开始交易 配方存在(0.2 毫秒)SELECT 1 作为一个 FROM "recipes" WHERE "recipes"."image" = ?限制 1 [["image", "1455332407-84040-0233/Honey-Mustard-Chicken-and-Apples.jpg"]] SQL(0.4 毫秒)插入 "recipes"("title"、"image"、"user_id"、"created_at"、"updated_at")值(? , ?, ?, ?, ?) [["title", "Honey Apple Chicken"], ["image", "1455332407-84040-0233/Honey-Mustard-Chicken-and-Apples.jpg"], ["user_id", 1], ["created_at", "2016-02-13 03:00:07.756946"], ["updated_at", "2016-02-13 03:00:07.756946"]] SQL(0.2 毫秒)插入 "ingredients"("name"、"recipe_id"、"created_at"、"updated_at")值(?、?、?、? ) [["name", "Chicken Thighs"], ["recipe_id", 1], ["created_at", "2016-02-13 03:00:07.758440"], [ "updated_at", "2016-02-13 03:00:07.758440"]] SQL(0.1 毫秒)插入 "ingredients"("name"、"recipe_id"、"created_at"、"updated_at")值(?、?、?、? ) [["name", "Honey"], ["recipe_id", 1], ["created_at", "2016-02-13 03:00:07.759655"], [ "updated_at", "2016-02-13 03:00:07.759655"]] (2.5ms) 提交事务 重定向至 http://localhost:3000/recipes/1 完成 302 在 1499 毫秒内找到(ActiveRecord:3.5 毫秒)
于 2016 年 2 月 12 日开始为 ::1 获取“/recipes/1”19:00:09-0800 RecipesController 处理#show as HTML 参数:{"id"=>"1"} 配方加载 (0.3ms) SELECT "recipes".* FROM "recipes" WHERE "recipes"."id" = ?限制 1 [["id", 1]] 用户负载 (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ?限制 1 [["id", 1]] 成分负载 (0.3ms) SELECT "ingredients".* FROM "ingredients" WHERE "ingredients"."recipe_id" = ? [["recipe_id", 1]] 方向负载 (0.1ms) SELECT "directions".* FROM "directions" WHERE "directions"."recipe_id" = ? [["recipe_id", 1]] 用户负载 (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ?按 "users"."id" 升序限制 1 [["id", 1]] 在 layouts/application(9.2 毫秒)内呈现 recipes/show.html.haml 在 47 毫秒内完成 200 OK(视图:41.2 毫秒 | ActiveRecord:1.0 毫秒)
我不明白 Karl 对他自己的问题的回答:Rails 4.1 Nested Attributes and Fields For Getting Unpermitted Parameters and Not Saving 如果你能看到任何东西,你就是 Macgyver!
您可以更改:
params.require(:recipe).permit(:title, :image, directions_attributes: [:id, :name, :_destroy], ingredients_attributes: [:id, :name, :_destroy])
为
params.require(:recipe).permit(:title, :image, directions_attributes: [:id, :name, :step, :_destroy], ingredients_attributes: [:id, :name, :_destroy])
您尝试在不允许的情况下发送 "step",如果您在方向模型中对 setp 列进行了 not_blank 验证,则不会保存。