行動すれば次の現実

テック中心の個人ブログ

ルーティングをネストする際のresourcesとresourceの使い分け | Rails

Railsで開発したことがある方は、ルーティングをネストしようとした場合に、resourcesとresourceのどちらを使用すべきか迷ってしまったことがあるのではないでしょうか?(私もその一人です)

この記事ではresourcesとresourceの使い分けについて、親リソースをブログ記事(topicsテーブル)と見立てて、わかりやすく解説をいたします。

子リソースのCRUDを定義したい場合はresources

親リソースに子リソースが属している場合は「resources」を使用します。 例えば、ブログ記事(親リソース)に対して、コメント(子リソース)を付くようなケースが該当します。

「親:子」は「1:N」なのでCRUDの全てのアクションが定義されます。

routes.rb
resources :topics do
    resources :comments, module: 'topics'
end
routing一覧
    topic_comments GET    /topics/:topic_id/comments(.:format)            topics/comments#index
                   POST   /topics/:topic_id/comments(.:format)            topics/comments#create
 new_topic_comment GET    /topics/:topic_id/comments/new(.:format)        topics/comments#new
edit_topic_comment GET    /topics/:topic_id/comments/:id/edit(.:format)   topics/comments#edit
     topic_comment GET    /topics/:topic_id/comments/:id(.:format)        topics/comments#show
                   PATCH  /topics/:topic_id/comments/:id(.:format)        topics/comments#update
                   PUT    /topics/:topic_id/comments/:id(.:format)        topics/comments#update
                   DELETE /topics/:topic_id/comments/:id(.:format)        topics/comments#destroy

親リソースにCRUD以外の振る舞いを定義したい場合はresource

親リソースに対してCRUD以外の振る舞いを定義したい場合は「resource」を使用します。 例えば、ブログ記事(親リソース)に対して、更新予約(子リソース)をするようなケースが該当します。

あくまでも親リソースに対しての振る舞いなので子リソース側にindexアクションは定義されません。

routes.rb
resources :topics do
  resource :comments, module: 'topics'
end
routing一覧
new_topic_comments  GET    /topics/:topic_id/comments/new(.:format)             topics/comments#new
edit_topic_comments GET    /topics/:topic_id/comments/edit(.:format)            topics/comments#edit
     topic_comments GET    /topics/:topic_id/comments(.:format)                 topics/comments#show
                    PATCH  /topics/:topic_id/comments(.:format)                 topics/comments#update
                    PUT    /topics/:topic_id/comments(.:format)                 topics/comments#update
                    DELETE /topics/:topic_id/comments(.:format)                 topics/comments#destroy
                    POST   /topics/:topic_id/comments(.:format)                 topics/comments#create

ルーティング定義はセンスが大事

明確なルールの元、正しくルーティング定義をしなければ保守性の高いシステムは作れません。

ルールを統一すると、ルーティングを見ただけでどのようなシステムなのか把握できる上、コントローラーのスコープが明確になります。 なんとなくルーティングを定義するのではなく、美しくルーティングを定義できるようにセンスを日々磨いていくことが重要であると私は考えます。