Ruby on rails 如何获取强参数以允许属性的嵌套字段_?
我有一个带有嵌套字段的表单。我试图允许该嵌套表单生成的参数,但它们被强参数阻止。我使用的是rails 4.2.4和ruby 2.2.2 我读过一些官方文件:Ruby on rails 如何获取强参数以允许属性的嵌套字段_?,ruby-on-rails,ruby-on-rails-4,strong-parameters,Ruby On Rails,Ruby On Rails 4,Strong Parameters,我有一个带有嵌套字段的表单。我试图允许该嵌套表单生成的参数,但它们被强参数阻止。我使用的是rails 4.2.4和ruby 2.2.2 我读过一些官方文件: 我读过相关的文章: 我读过各种博客文章: 还有更多 我想我是按照他们说的做的,但是我的嵌套属性被强参数拒绝了。我在我的日志中得到了类似于未经允许的参数:\uuuuu模板\uu行\uuuu、0、1、2、3 这是我的密码: 型号/附件.rb class Enclosure < ActiveRecord::Base
- 还有更多
未经允许的参数:\uuuuu模板\uu行\uuuu、0、1、2、3
这是我的密码:
型号/附件.rb
class Enclosure < ActiveRecord::Base
has_many :resident_animals, -> { order("year DESC, month DESC") }, dependent: :restrict_with_error
validates :name, presence: true, uniqueness: {case_sensitive: false}
accepts_nested_attributes_for :resident_animals, allow_destroy: true, reject_if: :all_blank
def to_s
name
end
end
class ResidentAnimal < ActiveRecord::Base
belongs_to :enclosure
validates_presence_of :enclosure, :year, :month, :color
...
end
class EnclosuresController < ApplicationController
...
def update
@enclosure = Enclosure.find(params[:id])
@enclosure.update(enclosure_params)
respond_with @enclosure
end
private
def enclosure_params
params.require(:enclosure).permit(:name, :description, resident_animals_attributes: [:year, :month, :color, :id, :_destroy])
end
end
<p class="field">
<%= form.label :name %>
<%= form.text_field :name %>
</p>
<p class="field">
<%= form.label :description %>
<%= form.text_area :description %>
</p>
<fieldset>
<legend>Resident Animals</legend>
<table id="resident-animal-rows">
<thead>
<th>Year <span class="required-field">*</span></th>
<th>Month <span class="required-field">*</span></th>
<th>Color <span class="required-field">*</span></th>
<th>Remove</th>
</thead>
<tbody>
<%= form.fields_for :resident_animals_attributes, ResidentAnimal.new(channel: form.object, year: Date.current.year, month: Date.current.month), index: "__template_row__" do |resident_animal_fields| %>
<tr class="resident-animal-row row-template">
<td><%= resident_animal_fields.number_field :year %></td>
<td><%= resident_animal_fields.select :month, month_options, include_blank: true %></td>
<td><%= resident_animal_fields.text_field :color %></td>
<td class="checkbox-cell"><%= resident_animal_fields.check_box :_destroy %></td>
</tr>
<% end %>
<%= form.fields_for :resident_animals do |resident_animal_fields| %>
<tr class="resident-animal-row">
<td><%= resident_animal_fields.number_field :year %></td>
<td><%= resident_animal_fields.select :month, month_options, include_blank: true %></td>
<td><%= resident_animal_fields.text_field :color %></td>
<td class="checkbox-cell">
<%= resident_animal_fields.hidden_field :id %>
<%= resident_animal_fields.check_box :_destroy %>
</td>
</tr>
<% end %>
</tbody>
</table>
<%= link_to "Add resident animal", "#", class: "resident-animal-row-add" %>
</fieldset>
调用enclosure_params返回:
{"name"=>"Polar Quest", "description"=>"Polar bear attraction", "resident_animals_attributes"=>{}}
我做错了什么
def enclosure_params
params.require(:).permit(:name, :description,
resident_animals_attributes: [:enclosure_id, :year, :month, :color]
)
end
我建议您使用更新的rails验证格式:
validates: :enclosure_id, presence: true
validates: :year, presence: true
validates: :month, presence: true
validates: :color, presence: true
如果您确实需要在常驻动物身上设置围栏,则可能需要在依赖模型上使用“反向”。我不确定你是否需要验证
错误是指这一行
<%= form.fields_for :resident_animals_attributes, ResidentAnimal.new(channel: form.object, year: Date.current.year, month: Date.current.month), index: "__template_row__" do |resident_animal_fields| %>
您没有定义索引属性。尝试删除该键值对。谢谢
我将在这里添加您评论中的正确答案,以便这个问题有一个正确的答案:
问题在于.permit
-使用包含ID作为键的嵌套哈希和包含其他属性作为值的哈希是一种特殊情况(很明显,因为它与.permit
的典型参数结构不匹配)
诀窍是:当且仅当所有键都转换为整数时,该算法检测特例(之所以调用,是因为它是字段(u for
helper)通常提交的参数样式)!因此,如果在密钥集中有一个非整数值(例如\uuu template\u row\uuuu
或new\u record\u id
),它将不会检测特殊情况,而是拒绝哈希中未明确允许的每个密钥(对于任何典型哈希)
为了避免这种情况,考虑到原始帖子中参数的结构,您只需删除作为模板行一部分提交的非整数键和属性:
def enclosure_params
params[:enclosure][:resident_animals_attributes].delete(:__template_row__)
params.require(:enclosure).permit(...) # (no change from OP)
end
(当然,这意味着,您应该确保您的接口不会尝试提交有意义的数据作为模板行的一部分);) 多谢各位。这与当时发生的事情非常接近,所以我能够找到它。问题是params中存在key
“\uuuu template\u row\uuuu”
,这导致它拒绝整个过程。如果我在使用强参数之前从散列中删除了该键值对,它将修复我的问题。如果你想更新你的答案,我会接受你的帮助。谢谢。我不确定你认为我的答案应该如何更新。
index: "__template_row__" do |resident_animal_fields|
def enclosure_params
params[:enclosure][:resident_animals_attributes].delete(:__template_row__)
params.require(:enclosure).permit(...) # (no change from OP)
end