Неизвестный параметр в проблеме с сильными параметрами Rails 5.1

Итак, моя модель 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

Когда я проверил HTML для входных данных в моей форме, внутри 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>

Вот как выглядит HTML, когда simple_field_for :inventory_item стоит в единственном числе:

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

person marcamillion    schedule 25.03.2018    source источник
comment
не могли бы вы обновить это <%= f.simple_fields_for :inventory_item do |inventory| %> этим <%= f.simple_fields_for :inventory_items do |inventory| %>   -  person uzaif    schedule 25.03.2018
comment
@uzaif Это было еще кое-что, что я пробовал. Когда я это делаю, вся форма внутри simple_fields_for по какой-то странной причине полностью исчезает. Я обновил вопрос с помощью HTML из этой попытки.   -  person marcamillion    schedule 25.03.2018
comment
accepts_nested_attributes_for :inventory_items ваша эта строка говорит, что у вас должно быть simple_form_fields с inventory_items вы создали элемент инвентаря в действии контроллера?   -  person uzaif    schedule 25.03.2018
comment
@uzaif О да .... Я ... обновляю, чтобы проверить обновленный вопрос. Я добавил больше кода в раздел контроллера и new.html.erb, который вызывает партиал _form.   -  person marcamillion    schedule 25.03.2018
comment
Дело в том, что я пытаюсь разобрать только 1 inventory_item при каждом рендеринге представления new.html.erb. Поэтому он так устроен.   -  person marcamillion    schedule 25.03.2018
comment
Вы можете поделиться со мной репозиторием? чтобы я мог изучить его   -  person uzaif    schedule 25.03.2018
comment
Хорошо, конечно... дай мне свой адрес электронной почты. Это частное репо на GH, поэтому мне нужно добавить вас так.   -  person marcamillion    schedule 25.03.2018
comment
Давайте продолжим обсуждение в чате.   -  person uzaif    schedule 25.03.2018


Ответы (2)


Я попытался просто добавить :inventory_item в мой params.require(:reconciliation).permit(..), но это не работает.

Если вы хотите разрешить inventory_item, вы должны указать его структуру, потому что это не простое поле, а хэш:

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

Вы можете добавить его как скрытое поле во вложенной форме.

person Pablo    schedule 05.04.2018

Форма ассоциации должна быть во множественном числе 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 ассоциации http://guides.rubyonrails.org/association_basics.html#choosing-between-has-many-through-and-имеет-и-принадлежит-ко-многим

Проще добавить объекты модели соединения с необходимыми полями и ассоциациями.

Еще один совет: не отправляйте локальную переменную в партиал, если вы используете переменную экземпляра в этом партиале.

# 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
person kolas    schedule 02.04.2018