🚀

Railsでリソースの一括操作がしたくなったら見る記事

2024/03/11に公開

前提

  • RailsはRESTfulな設計を前提としている
  • そのため、基本的にGET, POST, PATCH, DELETEの4つのHTTPメソッドは、単一のリソースの操作に対して行う

以上のことを前提に、それでも複数リソースを一括操作するユースケースが発生する場合は以下の方法を用いてる(あくまで一例)

Controllerに複数リソース用のメソッドを用意する

  • ex) /api/v1/users/の場合
    • POST /api/v1/users/bulk_createで複数ユーザーを一括作成
    • POST /api/v1/users/bulk_updateで複数ユーザーを一括更新
    • ...etc
# app/controllers/api/v1/users_controller.rb
module Api
  module V1
    class UsersController < ApplicationController
      def bulk_create
        # ...
      end

      def bulk_update
        # ...
      end
    end
  end
end

routes.rbにルーティングを追加する

  • membercollectionを使うってカスタムしたエンドポイントを作成
    • membercollectionの違いは、memberはリソースのIDを必要とするかどうか
    • リソースの一括操作はIDを必要としないので、collectionを使う方が適切
    Railsガイドからの抜粋
    resources :photos do
      collection do
        get 'search'
      end
    end
    

    上のルーティングは、GETリクエスト + /photos/searchなどの(idを伴わない)パスを認識し、リクエストをPhotosコントローラのsearchアクションにルーティングします。このときsearch_photos_urlやsearch_photos_pathルーティングヘルパーも同時に作成されます。

    詳細: Railsガイド: Rails のルーティング 2.10.2 コレクションルーティングを追加する

# config/routes.rb
Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :users, only: [] do
        collection do
          post :bulk_create
          post :bulk_update
        end
      end
    end
  end
end
  • 既存のHTTPメソッドと組み合わせる時は以下
# config/routes.rb
Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      resources :users, only: %i(create update) do
        collection do
          post :bulk_create
          post :bulk_update
        end
      end
    end
  end
end
  • rails cで確認すると以下のようなルーティングが確認できる
HTTPメソッド パス コントローラー#アクション 備考
POST /api/v1/users api/v1/users#create ユーザーを作成(通常のHTTPメソッド)
PATCH /api/v1/users/:id api/v1/users#update ユーザーを更新(通常のHTTPメソッド)
POST /api/v1/users/bulk_create api/v1/users#bulk_create 複数ユーザーを一括作成(カスタム)
POST /api/v1/users/bulk_update api/v1/users#bulk_update 複数ユーザーを一括更新(カスタム)

おわりに

次は、Railsにサービス層を追加するパターンとかも書いてみたいなぁと思ってます。

Discussion