有時候會有批次操作、刪除的需求,通常的作法都是在每個資料前面放一個 check box,然後送出時收集這些 id 做批次的操作。
舉例來說
你的 view 裡面可能是這樣
<%= form_tag bulk_update_admin_events_path do %>
<% @events.each do |event| %>
<tr>
<td>
<%= check_box_tag "ids[]", event.id %>
</td>
<tr>
<% end %>
<%= submit_tag "批次删除" %>
這時候 controller action 就可以做批次處理
def bulk_update
total = 0
Array(params[:ids]).each do |event_id|
event = Event.find(event_id)
event.destroy
total += 1
end
flash[:alert] = "成功完成 #{total} 笔"
redirect_to admin_events_path
end
這裡的一個小技巧我覺得非常有趣。
如果你是把 params[:ids]
直接拿去做 each,有可能發生使用者並沒有傳任何參數進來,也就是空值 nil
,那 nil.each 就會直接拋 NoMethodError
的錯誤,這邊就變成說你還要額外檢查 params[ids]
是否存在。
但如果用 Array(params[:ids])
就相當精巧
如果 Array([1, 2, 3])
會等同於 [1, 2, 3]
沒變 但是 Array[nil]
會變成 []
空集合,這樣就可以保證他在執行 .each
時不會出錯。
是一個很精巧的方法,之前參考來自於 ihower 在全棧營的教材裡提到。