Rails 4嵌套的属性哈希键显示为不允许 [英] Rails 4 nested attribute hash keys showing as unpermitted

查看:77
本文介绍了Rails 4嵌套的属性哈希键显示为不允许的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Category模型和一个Standard模型.类别通过联接表"模型CategoryStandard具有许多标准.在我看来,我有一个表单,可以在其中编辑类别描述,然后从该类别中添加或删除标准.因此,我的嵌套属性适用于:category_standards,因为我没有编辑标准本身,只是在有意义的情况下添加或删除了关系.

I have a Category model and a Standard model. A category has many standards through a "join table" model CategoryStandard. In my view, I have a form where I can edit the category description, and then add or remove standards from that category. So, my nested attributes are for :category_standards, because I'm not editing the standard itself, just adding or removing relationships, if that makes sense.

这是视图的重要部分:

<%= 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可以操纵行",但是效果很好,我认为这不是我的问题的一部分,因此我将其省略.

There's some jQuery under the hood to manipulate the "rows", but that works fine and I don't think it's part of my problem, so I'll omit it.

在我的类别"模型中,我有:

In my Category model, I have:

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

在我的类别控制器中,我有:

And in my Categories controller, I have:

def category_params
  params.require(:category).permit(:description, category_standards_attributes: [:id, :standard_id, :_destroy])
end

但是当我尝试向类别中添加标准时,我在服务器日志中获得了以下几行(经过重新格式化以希望使其更具可读性):

But when I try to add a standard to a category, I get these lines in my server log (reformatted in the hopes of making it more readable):

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]]

它可以很好地更新描述字段,但是Unpermitted参数如何处理?我的属性哈希值与嵌套表格上的《 Rails指南》中的示例一样,它甚至说::addresses_attributes哈希的关键字并不重要,每个地址只需要不同即可."但这是我无法获得的钥匙.

It updates the description field just fine, but what's up with the Unpermitted parameters? My attributes hash comes out just like the example in the Rails Guide on nested forms, and it even says "The keys of the :addresses_attributes hash are unimportant, they need merely be different for each address." And yet it's the keys that are getting denied for me.

我哪里出问题了?谢谢!

Where have I gone wrong? Thanks!

推荐答案

弄清楚了.丢失的部分是此处.

Figured it out, after a lot of reading. The missing piece was here.

带有整数键的哈希被区别对待,您可以将属性声明为直接子级.当将hass_many关联与accepts_nested_attributes_for结合使用时,您会得到以下类型的参数:

Hashes with integer keys are treated differently and you can declare the attributes as if they were direct children. You get these kinds of parameters when you use accepts_nested_attributes_for in combination with a has_many association:

# 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子句过滤掉了.

The important part of that was "Hashes with integer keys". My hash keys were passing as "0", "new_id", "1240934304343". It isn't important that I use "new_id", because that's just a placeholder value that gets changed in my jQuery when new rows are added. Only the template row retains that value, which is fine, because it gets filtered out by my reject_if clause.

但是"new_id"不是整数的事实显然是在搞砸了.因此,我将其更改为Rails可以接受的"-1"(即使它仍然被reject_if过滤掉了,也应该如此).

But the fact that "new_id" isn't an integer apparently was the thing that was mucking it all up. So I changed it to "-1", which Rails accepts (even though it is still filtered out by reject_if, as it should be).

<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>

这篇关于Rails 4嵌套的属性哈希键显示为不允许的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆