【问题标题】:Unpermitted parameter for array with dynamic keys具有动态键的数组的不允许参数
【发布时间】:2015-07-21 10:49:00
【问题描述】:

我试图允许具有任意数量值的数组,但 Rails 每次都会抛出 Unpermitted parameter: service_rates。我尝试了很多东西(Rails 4 Unpermitted Parameters for ArrayUnpermitted parameters for Dynamic Forms in Rails 4,...),但没有任何效果。

字段名称为service_rates,列类型为jsonb

我想从任意数量的输入字段创建一个 JSON 对象:

<%= f.hidden_field :service_ids, value: @services.map(&:id) %>
<% @services.each do |service| %>
  <tr>
    <td>
      <% value = @project.service_rates ? @project.service_rates["#{service.id}"]['value'] : '' %>
      <%= text_field_tag "project[service_rates][#{service.id}]", value, class: 'uk-width-1-1', placeholder: 'Stundensatz' %>
    </td>
  </tr>
<% end %>

所以我的POST 数据如下所示:

 project[service_rates][1] = 100
 project[service_rates][2] = 95
 project[service_rates][3] = 75

目前service_rates 可通过tap 列入白名单:

def project_params
  params.require(:project).permit(:field1, :field2, […], :service_ids).tap do |whitelisted|
    whitelisted[:service_rates] = params[:project][:service_rates]
  end
end

至少,我正在私有模型函数中构建一个 JSON 对象(这会引发此错误):

class Project < ActiveRecord::Base
  before_save :assign_accounting_content

  attr_accessor :service_ids

  private

  def assign_accounting_content

    if self.rate_type == 'per_service'
      service_rates = {}
      self.service_ids.split(' ').each do |id|
        service_rates["#{id}"] = {
          'value': self.service_rates["#{id}"]
        }
      end

      self.service_rates = service_rates
    end

  end

end

我也尝试过允许这样的字段......

params.require(:project).permit(:field1, :field2, […], :service_rates => [])

……还有那个……

params.require(:project).permit(:field1, :field2, […], { :service_rates => [] })

……但这也不起作用。

当我尝试这个时……

params.require(:project).permit(:field1, :field2, […], { :service_rates => [:id] })

…我明白了:Unpermitted parameters: 1, 3, 2

【问题讨论】:

  • 你能转储你的请求对象吗(它在传递给强参数之前的样子?)我最近遇到了这个。

标签: ruby-on-rails ruby-on-rails-4


【解决方案1】:

目前还不清楚service_rates 适合您。是协会的名字吗?还是只是一个字符串数组?

允许字符串数组::array =&gt; [], 允许嵌套参数进行关联:association_attributes: [:id, :_destroy, ...]

params.require(:object).permit(
  :something,
  :something_else,
  ....
  # For an array (of strings) : like this (AFTER every other "normal" fields)
  :service_rates => [],
  # For nested params : After standard fields + array fields
  service_rates_attributes: [
    :id,
    ...
  ]
)

正如我在 cmets 中解释的那样,顺序很重要。您的白名单数组必须出现在每个经典字段之后

编辑

您的表单应该使用f.fields_for 来表示嵌套属性

<%= form_for @project do |f| %>
    <%= f.fields_for :service_rates do |sr| %>
      <tr>
        <td>
          <%= sr.text_field(:value, class: 'uk-width-1-1', placeholder: 'Stundensatz' %>
        </td>
      </tr>
    <% end %>
<% end %>

【讨论】:

  • 谢谢,您为我指明了正确的方向。 service_rates 是一个(对象的)对象,而不是数组。是否可以允许具有任意(嵌套)键和值的散列?
  • 好吧,接受任意数量的键和值与 Rails 4 强参数相反。这样做是不安全的。但是您仍然可以使用params[service_rates] 访问参数
  • 是否可以动态允许密钥? service_rates 的内容类似于 '1': {'value': 10, 'active': true }, '2': {'value': 20, 'active': false }。键(12、...)是我的 Service 模型中记录的 ID。这行得通吗:permit({:service_rates =&gt; { HOW_TO_ADD_ALL_SERVICE_IDS_HERE? }})
  • 哦,你是这个意思。这是自动完成的,您不必担心。当你写service_rates_attributes: 时,它会自动允许service_rates的数组,所以你只需要指定service_rates_attributes: [:id, :value, :active]
  • 当我这样做时,我得到Unpermitted parameter: service_rates :((我使用的是 Rails 4.2.3)
猜你喜欢
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-25
  • 2017-06-28
相关资源
最近更新 更多