Simple_Form、嵌套资源和 Rails 5

Simple_Form, Nested Resources & Rails 5

我正在尝试让我的 simple_form 在嵌套资源上工作,但它不合作。

这些是我的模型:

location.rb:

# == Schema Information
#
# Table name: locations
#
#  id         :integer          not null, primary key
#  name       :string
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class Location < ApplicationRecord
  has_many :inventory_items, inverse_of: :location
  accepts_nested_attributes_for :inventory_items
end

inventory_item.rb:

# == Schema Information
#
# Table name: inventory_items
#
#  id                    :integer          not null, primary key
#  product_id            :integer
#  location_id           :integer
#  created_at            :datetime         not null
#  updated_at            :datetime         not null
#

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

这些是我的 routes.rb:

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

在这个路径:app/views/inventory_items/_form.html.erb,我有以下内容:

<%= simple_form_for [@location, @inventory_item] do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :product, collection: Product.all %>
    <%= f.input :location, as: :hidden, value: @location %>
  </div>

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

在我的 InventoryItemsController 中,我有这个:

  # GET /inventory_items/new
  def new
    @location = Location.find(params[:location_id])
    @inventory_item = InventoryItem.new
  end

  def create
    @inventory_item = InventoryItem.new(inventory_item_params)

    respond_to do |format|
      if @inventory_item.save
        format.html { redirect_to @inventory_item, notice: 'Inventory item was successfully created.' }
        format.json { render :show, status: :created, location: @inventory_item }
      else
        format.html { render :new }
        format.json { render json: @inventory_item.errors, status: :unprocessable_entity }
      end
    end
  end

我的 InventoryItemsController 中的强参数如下所示:

def inventory_item_params
  params.require(:inventory_item).permit(:product_id, :location_id)
end

这是我得到的错误:

Started POST "/locations/2/inventory_items" for 127.0.0.1 at 2018-02-28 02:12:08 -0500
Processing by InventoryItemsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"b37LkH+LTE/SCX6aepLQ==", "inventory_item"=>{"product"=>"1", "location"=>""}, "commit"=>"Create Inventory item", "location_id"=>"2"}
Unpermitted parameters: :product, :location
   (0.9ms)  BEGIN
   (1.1ms)  ROLLBACK
  Rendering inventory_items/new.html.erb within layouts/application
  Rendered inventory_items/_form.html.erb (209.3ms)
  Rendered inventory_items/new.html.erb within layouts/application (212.6ms)
Completed 500 Internal Server Error in 234ms (ActiveRecord: 2.0ms)

ActionView::Template::Error (undefined method `inventory_items_path' for #<#<Class:0x00007fb7cfeac4d0>:0x00007fb7d61c9630>
Did you mean?  inventory_item_path
               inventory_item_url):
    1: 
    2: <%= simple_form_for [@location, @inventory_item] do |f| %>
    3:   <%= f.error_notification %>
    4: 
    5:   <div class="form-inputs">

app/views/inventory_items/_form.html.erb:2:in `_app_views_inventory_items__form_html_erb__1010261120264584503_70213786161420'
app/views/inventory_items/new.html.erb:3:in `_app_views_inventory_items_new_html_erb__2144225759246708939_70213756146940'
app/controllers/inventory_items_controller.rb:35:in `block (2 levels) in create'
app/controllers/inventory_items_controller.rb:30:in `create'
Started PUT "/__web_console/repl_sessions/26d29444d640e5a02342d073be65f513" for 127.0.0.1 at 2018-02-28 02:12:31 -0500
Started PUT "/__web_console/repl_sessions/26d29444d640e5a02342d073be65f513" for 127.0.0.1 at 2018-02-28 02:12:33 -0500

我正在使用 Rails 5.1 和 Simple Form 3.5.1。

编辑 1

我尝试将 _form.html.erb 部分更改为:

<%= simple_form_for @inventory_item do |f| %>

我仍然收到 same/similar 错误:

Started GET "/locations/2/inventory_items/new" for 127.0.0.1 at 2018-02-28 13:07:01 -0500
Processing by InventoryItemsController#new as HTML
  Parameters: {"location_id"=>"2"}
  Location Load (1.4ms)  SELECT  "locations".* FROM "locations" WHERE "locations"."id" =  LIMIT   [["id", 2], ["LIMIT", 1]]
  Rendering inventory_items/new.html.erb within layouts/application
  Rendered inventory_items/_form.html.erb (180.4ms)
  Rendered inventory_items/new.html.erb within layouts/application (182.9ms)
Completed 500 Internal Server Error in 194ms (ActiveRecord: 1.4ms)



ActionView::Template::Error (undefined method `inventory_items_path' for #<#<Class:0x00007fb7cfeac4d0>:0x00007fb7d78025c8>
Did you mean?  inventory_item_path
               inventory_item_url):
    1: 
    2: <%= simple_form_for @inventory_item do |f| %>
    3:   <%= f.error_notification %>
    4: 
    5:   <div class="form-inputs">

app/views/inventory_items/_form.html.erb:2:in `_app_views_inventory_items__form_html_erb__1010261120264584503_70213731033440'
app/views/inventory_items/new.html.erb:3:in `_app_views_inventory_items_new_html_erb__2144225759246708939_70213785622700'

变化:app/views/inventory_items/_form.html.erb

<%= simple_form_for @inventory_item do |f| %>

似乎正确的答案只是将 url: 选项添加到 simple_form_for 辅助方法并将 f.input 的名称更改为 :product_id

所以我的 _form.html.erb 的最终版本看起来像这样:

<%= simple_form_for @inventory_item, url: :location_inventory_items do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :product_id, collection: Product.all %>
    <%= f.input :location_id, as: :hidden, value: @location %>
    <%#= f.input_field :avatar, as: :hidden, value: @profile.cached_avatar_data, class: 'col-lg-4 form-control '%>
  </div>

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