🌊

チェックボックスを使用したカラムの値を一括更新する方法

2024/05/26に公開

背景

実務で 商品のクーポンステータスを画面上から切り替えることができるようにする機能を作成することになりました。

その時の実装内容をチェックボックスのチェック状況からカラム(今回でいうとクーポンステータスを管理するカラム)の値を一括で更新する方法として記事にまとめたので、同じような実装をする時の参考にしていただけると幸いです。

完成イメージ(チェックボックスにチェックし、登録ボタンを押下することで、チェックボックスと紐づくカラムの値を更新しています。)

実装

config/routes.rb
Rails.application.routes.draw do
  resources :items do
    post "update_coupon_status", on: :collection
  end
end
app/controllers/items_controller.rb
def update_coupon_status
  if params[:item].present?
    params[:item].each do |item_id, item_attributes|
      item = Item.find(item_id)
      item.update(coupon_status: item_attributes[:coupon_status])
    end
  end

  redirect_to items_path, notice: 'クーポンステータスが更新されました。'
end
app/views/items/index.html.erb
<p style="text-align: center;" id="notice"><%= notice %></p>
<div style="text-align: center;">
  <h3>商品一覧</h3>
</div>
<div style="text-align: center;">
    <%= form_with url: update_coupon_status_items_path, html: { style: "display: inline-block; text-align: center;" } do |f| %>
    <table style="margin: auto; display: block; text-align: center;">
      <thead>
        <tr>
          <th>商品名</th>
          <th>クーポンステータス</th>
        </tr>
      </thead>

      <tbody>
        <% @items.each do |item| %>
          <tr>
            <td><%= item.name %></td>
            <td>
              <%= hidden_field_tag "item[#{item.id}][coupon_status]", "false" %>
              <%= check_box_tag "item[#{item.id}][coupon_status]", "true", item.coupon_status == true, { class: "center-checkbox" } %>
            </td>
          </tr>
        <% end %>
      </tbody>
    </table>
    <div style="margin: auto; text-align: center;">
      <%= f.submit '登録' %>
    </div>
  <% end %>
</div>

各ファイルを解説していきます。

config/routes.rb

このファイルは、アプリケーションのルーティングを設定するためのものです。resources :itemsは、アイテムに関するRESTfulなルーティングを自動生成します。そして、post "update_coupon_status", on: :collectionは、itemsリソースに対してのコレクションアクションとしてupdate_coupon_statusを追加しています。つまり、複数のアイテムをまとめて更新するアクションを定義しています。

app/controllers/items_controller.rb

このファイルは、アプリケーションのコントローラを定義するためのものです。update_coupon_statusメソッドは、クーポンステータスを更新するためのアクションです。送信されたパラメータからアイテムを取得し、それぞれのアイテムのクーポンステータスを更新します。そして、最後に商品一覧ページにリダイレクトします。

app/views/items/index.html.erb

このファイルは、商品一覧ページのビューを定義するためのものです。フォームを使って、アイテムのクーポンステータスを更新するUIを提供しています。各アイテムのクーポンステータスをチェックボックスで選択できるようにし、一括更新のためのフォームを作成しています。フォームが送信されると、update_coupon_statusアクションが呼び出されます。

ちなみにですが、上記の登録ボタンを押下し、サーバ側へデータを送信するときのパラメータは下記のような感じになります。

app/controllers/items_controller.rb
     9: def update_coupon_status
 => 10:   binding.pry
    11:   if params[:item].present?
    12:     params[:item].each do |item_id, item_attributes|
    13:       item = Item.find(item_id)
    14:       item.update(coupon_status: item_attributes[:coupon_status])
    15:     end
    16:   end
    17:
    18:   redirect_to items_path, notice: 'クーポンステータスが更新されました。'
    19: end

[1] pry(#<ItemsController>)> params
=> #<ActionController::Parameters {"authenticity_token"=>"XXXX", "item"=>{"1"=>{"coupon_status"=>"false"}, "3"=>{"coupon_status"=>"true"}, "4"=>{"coupon_status"=>"true"}, "5"=>{"coupon_status"=>"false"}, "6"=>{"coupon_status"=>"false"}}, "commit"=>"登録", "controller"=>"items", "action"=>"update_coupon_status"} permitted: false>

これにより、Ruby on Railsを使用して簡単に商品のクーポンステータスをチェックボックスで一括更新することができます。

参考

check_box_tag

https://railsdoc.com/page/check_box_tag

form_with 配列データを送信

https://railsguides.jp/form_helpers.html#パラメータの命名ルールを理解する

https://qiita.com/i_garasi/items/81952e8198308d70069e

https://ichiro-tanaka.hatenadiary.org/entry/20090417/1239979791

Discussion