#はじめに
私が業務でRailsアプリケーションのルーティングをカスタマイズ・整理したときのメモです。
Ruby on Rails Guidesに書いてある中で、これ使うぞと思うものを自分なりにピックアップしました。
最近Railsの開発をしていないので、もっといい方法をご存知の方がいらっしゃったら声を大にして教えていただけると嬉しいです。
#目次
- 基本形を自動生成しないで定義したいとき
- 階層構造をもったURLを定義したいとき
- オリジナルのActionをちょい足ししたいとき
- 複数のControllerにオリジナルのActionをちょい足ししたいとき
基本形を自動生成しないで定義したいとき
CRUD全てを定義したいときは以下のように書けばよいです。
自動生成しても同じ内容がroutes.rbに定義されます。
resources :book_shops
とはいえ、手動でルーティングを定義するときというのは、特定のActionへのルーティングだけを定義したいときだと思います。例えば、indexとshowしか使わないとか。そんな時はonly: [:許可するアクション]
と書けばOKです。
resources :book_shops, only: [:index, :show]
# 以下のように定義してもよいですが、面倒だと思います。
# get 'books', to 'books#index'
# get 'books/:id', to 'books#show'
階層構造をもったURLを定義したいとき
has-manyなどリレーションのあるModelについて実装をするときに起こりうると思います。
例えば、/book_shop/28/books
にアクセスさせて、IDが28番である本屋の蔵書一覧がわかるとか。
resources :book_shops do
resources : books
end
@scivola さんよりご指摘いただき、以下の表の内容を修正いたしました。
HTTP methods | Path | Controller#Action |
---|---|---|
GET | book_shops/:book_shop_id/books | book_shop#index |
GET | book_shops/:book_shop_id/books/new | book_shop#new |
POST | book_shops/:book_shop_id/books | book_shop#create |
GET | book_shops/:book_shop_id/books/:id | book_shop#show |
GET | book_shops/:book_shop_id/books/:id/edit | book_shop#edit |
PUT/PATCH | book_shops/:book_shop_id/books/:id | book_shop#update |
DELETE | book_shops/:book_shop_id/books/:id | book_shop#destroy |
ネストさせる場合も、特定のActionへのルーティングのみ定義することができます。
後ろにonly: [:許可するアクション]
と書けばOKです。
resources :book_shops do
resources : books, only: [:index, :show]
end
オリジナルのActionをちょい足ししたいとき
##/controller/:id/action
形式
例えば、指定した書籍をダウンロードするActionへのルーティングを定義するには、以下のように定義します。
resources :books do
member do
post 'download'
# post 'download', on: :memberでもOK
do
基本形に同じくpost 'books/:id/download', to 'book#download'
と任意の場所に定義してもよいですが、私は推奨しません。
同じControllerに対するルーティングは1か所に書いたほうがメンテナンスしやすいからです。バラバラの場所に書くと、何が定義されていて何が定義されていないのか管理するのが大変になります。
##/controller/action
形式
例えば、書籍の一覧に対して検索をするActionへのルーティングを定義するには、以下のように定義します。
resources :books do
collection do
get 'search'
# get 'search', on: :collectionでもOK
do
複数のControllerにオリジナルのActionをちょい足ししたいとき
検索用のルーティングを用意したものの、そのActionって色んなところで使うのだけれどもという場合ですね。
ルーティングが一つだとうま味が少ないかと思いますので、以下のActionを追加してみたいと思います。
- 作成確認画面:
new_confirm
- 編集確認画面:
edit_confirm
- 削除確認画面:
delete_confirm
確認画面を足すとかあるあるですよね(たぶん)。
今までの知識でbook_shop_controllerとbook_controllerにルーティングを追加すると以下のようになるはずです。
resources :book_shops do
post 'new_confirm', on: :collection
member do
post 'edit_confirm'
post 'delete_confirm'
end
end
resources :books do
post 'new_confirm', on: :collection
member do
post 'edit_confirm'
post 'delete_confirm'
end
end
別にこれでもいんですけども、少し冗長ですよね。
今は2つしかないからよいですが、あとから機能追加で数十個もControllerを足すとなれば、routes.rbは地獄絵図と化すでしょう。
concern
を使えば、上のような冗長さを解決できます。
resources :book_shops, concerns: :confirmable
resources :books, concerns: :confirmable
concern :confirmable do
post 'new_confirm', on: :collection
member do
post 'edit_confirm'
post 'delete_confirm'
end
end
最高にイケてるルーティングになったような気がしますね(自画自賛)。
#補足
本当はControllerをサブディレクトリに分ける際のお話もしたかったのですが
ここまででも話が長くなってしまったので割愛させていただきます。
#参考ページ
Ruby on Rails Guides