【问题标题】:Unknown parameter in Rails 5.1 strong parameters issueRails 5.1 强参数问题中的未知参数
【发布时间】:2018-03-25 04:25:33
【问题描述】:

所以我的reconciliation 模型看起来像这样:

class Reconciliation < ApplicationRecord
  belongs_to :location
  belongs_to :company
  has_and_belongs_to_many :inventory_items
  accepts_nested_attributes_for :inventory_items, allow_destroy: true
end

我的InventoryItem 模型如下所示:

class InventoryItem < ApplicationRecord
  belongs_to :product
  belongs_to :location, inverse_of: :inventory_items
  has_and_belongs_to_many :reconciliations
end

在我的ReconciliationsController 中,这是我的reconciliation_params 的样子:

  def new
    @location = Location.find(params[:location_id])
    @reconciliation = @location.reconciliations.new
    @inventory_items = @location.inventory_items
    @start_index = 0
    @next_index = @start_index + 1
  end

def reconciliation_params
  params.require(:reconciliation).permit(:inventory_item_id, :location_id, :display_id, :inventory_items,
        inventory_items_attributes: [:id, :quantity_left, :quantity_delivered, :_destroy]
  )
end

这是我routes.rb的相关部分:

  resources :locations, shallow: true do
    resources :inventory_items
    resources :reconciliations
  end

这是我的views/reconciliations/_form.html.erb

<%= simple_form_for @reconciliation, url: :location_reconciliations do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :location_id, as: :hidden %>
    <%= f.simple_fields_for :inventory_item do |inventory| %>
      <%= inventory.input :quantity_left %>
      <%= inventory.input :quantity_delivered %>
    <% end %>
  </div>

  <div class="form-actions">
      <%= f.button :submit, "Update", class: "btn btn-primary" %>
  </div>
<% end %>

这是我的app/views/reconciliations/new.html.erb

<% if params[:next].nil? %>
  <%= render 'form', reconciliation: @reconciliation, inventory_item: @inventory_items[@start_index] %>
<% else %>
  <%= render 'form', reconciliation: @reconciliation, inventory_item: @inventory_items[@next_index] %>
<% end %>

这是我尝试创建reconciliation 对象时的日志:

Started POST "/locations/2/reconciliations" for 127.0.0.1 at 2018-03-24 23:16:33 -0500
Processing by ReconciliationsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"JZvhwloo0+XM9bmptxXGfnDw==", "reconciliation"=>{"location_id"=>"2", "inventory_item"=>{"quantity_left"=>"1", "quantity_delivered"=>"170"}}, "commit"=>"Update", "location_id"=>"2"}
Unpermitted parameter: :inventory_item
  Location Load (0.9ms)  SELECT  "locations".* FROM "locations" WHERE "locations"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]
   (0.6ms)  BEGIN
   (0.7ms)  ROLLBACK
  Rendering reconciliations/new.html.erb within layouts/application
  InventoryItem Load (1.0ms)  SELECT "inventory_items".* FROM "inventory_items" WHERE "inventory_items"."location_id" = $1  [["location_id", 2]]
  Product Load (1.0ms)  SELECT  "products".* FROM "products" WHERE "products"."id" = $1 LIMIT $2  [["id", 2], ["LIMIT", 1]]
  Rendered reconciliations/_form.html.erb (45.9ms)
  Rendered reconciliations/new.html.erb within layouts/application (66.8ms)
  Rendered shared/_navbar.html.erb (1.3ms)
Completed 200 OK in 202ms (Views: 115.1ms | ActiveRecord: 29.1ms)

我尝试简单地将:inventory_item 添加到我的params.require(:reconciliation).permit(..),但这不起作用。

我错过了什么?

编辑 1

当我在simple_fields_for 中检查表单上的输入时,HTML 似乎没问题:

<input class="string required" type="text" name="reconciliation[inventory_item][quantity_left]" id="reconciliation_inventory_item_quantity_left">

编辑 2

当我将simple_fields_for 调用更改为复数时,即:inventory_items,而不是像这样的:inventory_item

表格的整个部分完全消失了。

这就是 HTML 的样子:

<div class="form-inputs">
    <div class="input hidden reconciliation_location_id"><input class="hidden" type="hidden" value="2" name="reconciliation[location_id]" id="reconciliation_location_id"></div>
</div>

这就是simple_field_for :inventory_item 是单数时 HTML 的样子:

<div class="form-inputs">
    <div class="input hidden reconciliation_location_id"><input class="hidden" type="hidden" value="2" name="reconciliation[location_id]" id="reconciliation_location_id"></div>

      <div class="input string required reconciliation_inventory_item_quantity_left"><label class="string required" for="reconciliation_inventory_item_quantity_left"><abbr title="required">*</abbr> Quantity left</label><input class="string required" type="text" name="reconciliation[inventory_item][quantity_left]" id="reconciliation_inventory_item_quantity_left"></div>
      <div class="input string required reconciliation_inventory_item_quantity_delivered"><label class="string required" for="reconciliation_inventory_item_quantity_delivered"><abbr title="required">*</abbr> Quantity delivered</label><input class="string required" type="text" name="reconciliation[inventory_item][quantity_delivered]" id="reconciliation_inventory_item_quantity_delivered"></div>
  </div>

【问题讨论】:

  • 你能用这个&lt;%= f.simple_fields_for :inventory_items do |inventory| %&gt;更新这个&lt;%= f.simple_fields_for :inventory_item do |inventory| %&gt;
  • @uzaif 这也是我尝试过的其他方法。当我这样做时,simple_fields_for 中的整个表单会因为某种奇怪的原因而完全消失。我用那次尝试的 HTML 更新了问题。
  • accepts_nested_attributes_for :inventory_items 你的这条线说你应该有simple_form_fieldsinventory_items 你在控制器操作中建立了库存项目吗?
  • @uzaif 哦耶....我愿意...刷新以检查更新的问题。我在控制器部分和new.html.erb 中添加了更多代码,它调用了_form 部分。
  • 问题是,我试图在 new.html.erb 视图的每个渲染上仅解析 1 个 inventory_item。这就是为什么它是这样设置的。

标签: ruby-on-rails ruby-on-rails-5 simple-form strong-parameters ruby-on-rails-5.1


【解决方案1】:

我尝试简单地将 :inventory_item 添加到我的 params.require(:reconciliation).permit(..),但这不起作用。

如果你想允许inventory_item,你必须指定它的结构,因为它不是一个简单的字段,而是一个hash:

def reconciliation_params
  params.require(:reconciliation).permit(:location_id, :display_id, inventory_item: [:id, :quantity_left, :quantity_delivered] )
end

通过查看您的日志,您没有传递inventory_item_id,更新此特定项目可能需要它:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"JZvhwloo0+XM9bmptxXGfnDw==", 
"reconciliation"=>{"location_id"=>"2", "inventory_item"=>
{"quantity_left"=>"1", "quantity_delivered"=>"170"}},
"commit"=>"Update", "location_id"=>"2"}

您可以将其添加为嵌套表单中的隐藏字段。

【讨论】:

    【解决方案2】:

    关联形式应该是复数f.simple_fields_for :inventory_items。 您应该在新控制器的操作中初始化一个新的 inventory_item 对象

    def new
      @reconciliation = Reconciliation.new
      # you can create as many new items as you want
      @reconciliation.inventory_items.build
    end
    

    如果您想动态添加项目到表单中,我建议您使用https://github.com/nathanvda/cocoon

    但您似乎想将现有inventory_item 添加到新的对帐中,您最好使用has_many through assocations http://guides.rubyonrails.org/association_basics.html#choosing-between-has-many-through-and-has-and-belongs-to-many

    添加具有必要字段和关联的连接模型对象更容易。

    另一个建议:如果您在此部分中使用实例变量,请不要将局部变量发送到部分

    # render partial
    render 'form', reconciliation: @reconciliation
    # partial with form for local variable
    simple_form_for reconciliation
    

    而且我认为由于硬编码的 url,您的表单部分不适用于编辑操作,您可以在变量中传递 url:

    # new html
    render 'form', reconciliation: @reconciliation, url_var: location_reconciliations(@location)
    # edit
    render 'form', reconciliation: @reconciliation, url_var: reconciliations(@reconciliation)
    # form
    simple_form_for reconciliation, url: url_var
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-19
      • 1970-01-01
      • 2013-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多