我有Category
模型和Standard
模型。一个类别通过“连接表”模型CategoryStandard
有许多标准。在我看来,我有一个表单,我可以编辑类别描述,然后添加或删除该类别的标准。所以,我的嵌套属性适用于:category_standards
,因为我没有编辑标准本身,只是添加或删除关系,如果这是有意义的。
以下是该观点的重要部分:
<%= form_for(@category) do |f| %>
...
<div class="field">
<%= f.label :description %>
<%= f.text_field :description %>
</div>
<%= label_tag nil, "Standards in this Category" %>
<div id="standard-list">
<%= f.fields_for :category_standards do |ff| %>
<div class="field">
<%= ff.object.standard.number_with_exceptions %>
<%= ff.hidden_field :standard_id %>
<%= ff.hidden_field :_destroy %>
<%= link_to "<span class='glyphicon glyphicon-remove'></span>".html_safe, "", class: "del-std-btn", title: "Remove standard from category" %>
</div>
<% end %>
<div class="hidden" id="std-add-new-template">
<div class="field">
<%= f.fields_for :category_standards, CategoryStandard.new, child_index: "new_id" do |ff| %>
<%= ff.collection_select :standard_id, @standards - @category.standards, :id, :number_with_exceptions, prompt: "Select a standard to add" %>
<% end %>
</div>
</div>
</div>
...
<% end %>
有一些jQuery来操纵“行”,但是工作正常,我不认为这是我问题的一部分,所以我会省略它。
在我的分类模型中,我有:
class Category < ActiveRecord::Base
has_many :category_standards, dependent: :destroy
has_many :standards, through: :category_standards
validates :description, presence: true,
uniqueness: true
accepts_nested_attributes_for :category_standards, allow_destroy: true, reject_if: proc { |attributes| attributes['standard_id'].blank?}
end
在我的分类控制器中,我有:
def category_params
params.require(:category).permit(:description, category_standards_attributes: [:id, :standard_id, :_destroy])
end
但是当我尝试将标准添加到某个类别时,我会在服务器日志中添加这些行(为了使其更具可读性而重新格式化):
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"***********",
"category"=>{
"description"=>"Drinking Water System Components",
"category_standards_attributes"=>{
"0"=>{
"standard_id"=>"2",
"_destroy"=>"false",
"id"=>"1"
},
"new_id"=>{
"standard_id"=>""
},
"1424899001814"=>{
"standard_id"=>"1"
}
}
},
"commit"=>"Save Changes",
"id"=>"2"
}
User Load (5.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
Category Load (4.0ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" = $1 LIMIT 1 [["id", "2"]]
Unpermitted parameters: 0, new_id, 1424899001814
(4.0ms) BEGIN
Category Exists (6.0ms) SELECT 1 AS one FROM "categories" WHERE ("categories"."description" = 'Drinking Water System Components' AND "categories"."id" != 2) LIMIT 1
SQL (6.0ms) UPDATE "categories" SET "description" = $1, "updated_at" = $2 WHERE "categories"."id" = 2 [["description", "Drinking Water System Components"], ["updated_at", Wed, 25 Feb 2015 21:16:44 UTC +00:00]]
它更新了描述字段,但是未经许可的参数是什么?我的属性哈希就像nested forms上的Rails指南中的示例一样,它甚至说:“addresses_attributes哈希的键是不重要的,它们只需要对每个地址都不同。”然而,这是被我拒绝的钥匙。
我哪里出错了?谢谢!
答案 0 :(得分:1)
经过大量阅读后想出来了。缺失的部分是here。
具有整数键的哈希值的处理方式不同,您可以将属性声明为直接子项。当您将accepts_nested_attributes_for与has_many关联结合使用时,您会获得以下类型的参数:
# To whitelist the following data:
# {"book" => {"title" => "Some Book",
# "chapters_attributes" => { "1" => {"title" => "First Chapter"},
# "2" => {"title" => "Second Chapter"}}}}
params.require(:book).permit(:title, chapters_attributes: [:title])
其中重要的部分是“具有整数键的哈希”。我的哈希键传递为“0”,“new_id”,“1240934304343”。使用“new_id”并不重要,因为这只是一个占位符值,当我添加新行时,我的jQuery会改变它。只有模板行保留该值,这很好,因为它被我的reject_if
子句过滤掉了。
但是“new_id”不是整数的事实显然是把它全部搞砸了。所以我把它改为“-1”,Rails接受了(即使它仍被reject_if
过滤掉了,因为它应该是)。
<div class="hidden" id="std-add-new-template">
<div class="field">
<%= f.fields_for :category_standards, CategoryStandard.new, child_index: "-1" do |ff| %>
<%= ff.collection_select :standard_id, @standards - @category.standards, :id, :number_with_exceptions, prompt: "Select a standard to add" %>
<% end %>
</div>
</div>
答案 1 :(得分:0)
您的属性键似乎与您在强参数中的预期不符,“new_id”和“1424899001814”肯定不会被允许。
"new_id"=>{
"standard_id"=>""
},
"1424899001814"=>{
"standard_id"=>"1"
}
我怀疑你构建表单的方式无效。尝试将其分解为最简单的工作形式..例如:
<div id="standard-list">
<%= link_to "<span class='glyphicon glyphicon-remove'></span>".html_safe, "", class: "del-std-btn", title: "Remove standard from category" %>
<div class="hidden" id="std-add-new-template">
<div class="field">
<%= f.fields_for :category_standards do |ff| %>
<%= ff.object.standard.number_with_exceptions %>
<%= ff.hidden_field :standard_id %>
<%= ff.hidden_field :_destroy %>
<%= ff.collection_select :standard_id, @standards - @category.standards, :id, :number_with_exceptions, prompt: "Select a standard to add" %>
<% end %>
</div>
</div>
</div>
目的是只有一个嵌套的表单,通过剥离它只创建一个嵌套的哈希。
"category_standards_attributes"=>{
"0"=>{
"standard_id"=>"2",
"_destroy"=>"false",
"id"=>"1"
}
}
这会发生什么?