coding with alpaca -46 使用者可以線上下 order

rails g controller orders

class OrdersController < ApplicationController
  before_action :authenticate_user!
before_action :set_purchase
  def update
@order = Order.find(params[:id])
if @order.update(order_params)
redirect_to purchase_path(@purchase)
else
render 'purchase/show'
end
end
private
  def order_params
params.require(:order).permit(ordered_items_attributes: [:id,
:item_id, :quantity, :_destroy])
end
  def set_purchase
@purchase = Purchase.find(params[:purchase_id])
end
end

purchase 跟 order 的關係(order under 在 purchase 底下),就跟 store 和 item 一樣(item under 在 store 底下)

def order_params 的標準格式:

params.require(:order).permit(想要修改的表單_attributes: [:join table 的 id, :想要修改的欄位名稱, :_destroy])

routes

resources :purchases do
resources :orders
end

問題是…

user 不能改 user_id 跟 purchase_id,其實可以改的是 ordered_items table

要透過 order model 修改 ordered_item model,就要開啟 order.rb,新增:

accepts_nested_attributes_for :ordered_items, allow_destroy: true

就可以針對其他表格塞入 nested_attributes(想要修改的表格名稱,後面加上 _attributes,例如 ordered_items_attributes)

order_params
{
:ordered_items_attributes => {
:'0' => {
:id => 1
:quantity => 3
}
}
}

到 purchases/show.html.erb,新增:

<%= form_for [@purchase, @order] do |f| %>
# 傳入兩個實例變數
<%= f.fields_for :ordered_items do |item_form| %>

<%= item_form.collection_select :item_id, @purchase.store.items,
:id, :name %>
<%= item_form.number_field :quantity %>
  <% end %>
<% end %>

form_for 是表單的 helper

fields_for 是修改欄位的 helper,後綴要修改的表單名稱

purchases_controller

def show
@purchase = Purchase.find(params[:id])
@order = Order.find_by(user: current_user, purchase: @purchase)
end

總的來說步驟:

  1. rails g controller orders
  2. routes, 把 order 包在 purchase 裡面
  3. 到 order.rb, 新增 accepts_nested_attributes_for
  4. 編輯 order 的 show 頁面 (本例 order 是顯示在 purchases/show)
  5. 承上,所以要修改 purchase controller,把 @order 傳進 purchases/show 頁面
A single golf clap? Or a long standing ovation?

By clapping more or less, you can signal to us which stories really stand out.