使用form_tag传输参数

时间:2018-11-13 15:23:24

标签: ruby-on-rails

在我看来,我有一个表格,正在尝试更新订单行的数量:

<div class="quantity">Quantity</br> 
    <%= form_tag(order_line_path(line.id), method: "patch") do  %>
        <%= number_field_tag 'qty', '1', within: 1...line.book.stock %>
        <%= submit_tag "Update", class: "btn btn-primary" %>
    <% end %>
</div>

我其余视图中的实例变量是订单行的集合,所以我不能使用它。

然后我的控制器中有更新方法:

def update
  @order = current_order
  @order_line = @order.order_lines.find(params[:id])
  @order_line.update_attributes(order_line_params)
end

我强大的参数定义:

def order_line_params
  params.require(:order_line).permit(:qty)
end

我收到此错误:

param is missing or the value is empty: order_line

有人可以看看吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

获得param is missing or the value is empty: order_line的原因是您使用的form_tag给出了“平坦的”参数散列。

但是,只要使用form_with/form_for,就可以轻松避免这种情况。

# routes.rb
resources :orders do
  resources :line_items, shallow: true
end

# app/views/order_items/edit.html.erb
# use `form_with(model: @order_item)` in Rails 5
<%= form_for(@order_item) do |f| %>
  <%= f.label :qty, within: 1...f.object.book.stock %>
  <%= f.number_field :qty,  %>
  <%= f.submit %>
<% end %>

class OrderItemsController < ApplicationController

  before_action :set_order_item, only: [:show, :edit, :update, :destroy]

  # ...

  # GET /order_items/:id/edit
  def edit
  end 

  # PATCH /order_items/:id
  def update
    if @order_item.update(order_item_params)
      redirect_to @order_item, notice: 'Line updated'
    else
      render :edit
    end
  end

  private

    def set_order_item
      @order_item = OrderItem.find(params[:id])
    end

    def order_item_params
      params.require(:order_item).permit(:qty)
    end
end

但是,除非您使用AJAX进行嵌套项目的更新/创建,否则您真正要寻找的是accepts_nested_attributesfields_for的组合,这将使用户可以批量编辑行项目:

class Order < ApplicationRecord
  accepts_nested_attributes_for :order_items
end

<%= form_for(@order) do |f| %>
  <%= fields_for(:order_items) do |oif| %>
    <%= f.label :qty, within: 1...f.object.book.stock %>
    <%= f.number_field :qty,  %>
  <% end %>

  <%= f.submit %>
<% end %>

class OrdersController < ApplicationController
  # PATCH /orders/:id
  def update
    if @order.update(order_params)
      redirect_to @order, notice: 'Order updated.'
    else
      render :new
    end
  end

  private
    def order_params
      params.require(:order).permit(order_items_attributes: [:qty])
    end
end