はじめに
Railsのルーティングは、受け取ったURLを解析し、適切なコントローラーのメソッドに処理を移譲する役目を担います。ルーティングはMVCモデルの各機能と並んでRailsアプリの基幹機能のひとつだと言えます。
本記事では、Railsのルーティングの書き方についてまとめています。なお、ルーティングの書き方はたくさんありオプションも豊富に存在しますが、本記事ではよく使うであろう書き方のみ取り上げています。
ルーティング情報の確認
現在のルーティング情報を確認するには、以下のコマンドを実行します。
$ rails routes
上記のコマンドはすべてのルーティング情報を表示するので、ルーティングが増えてくると確認したい目的のルーティング情報を探すのが大変です。上記コマンドに-g
オプションをつけるとルーティング情報を絞り込むことができます。
$ rails routes -g users
また、-c
オプションをつけるとコントローラー名で絞り込むことができます。
$ rails routes -c articles
コマンドではなくブラウザで確認することもできます。テストサーバーを起動している状態でhttp://localhost:3000/rails/info/routes
にアクセスするとルーティング情報が表示されます。この方法ではパスの部分検索ができます。
ルーティングの書き方
ルーティングはconfig/routes.rb
に記述していきます。
基本の書き方
最も基本的な書き方は以下のようになります。
get '/', to: 'statics#index'
先頭にHTTPメソッドを記述し、次にURL、そして移譲するコントローラーとメソッドを記述します。使用できるHTTPメソッドは以下の通りです。
HTTPメソッド | 説明 |
---|---|
GET | 既存データを取得する。 |
POST | 新規データを作成する。 |
PUT | 既存データを更新する。 |
PATCH | 既存データを更新する(差分)。 |
DELETE | 既存データを削除する。 |
なお、上記の例はルートのルーティングを設定しているので、以下のように書くこともできます。ルートは最も基本となるルーティングなので、先頭に記述するのが望ましいです。
root 'statics#index'
Resourcefulルーティング
Resourcefulとは、Railsのルーティングにおいて、RESTful APIの統一インターフェースとほとんど同じ意味として使われています。
統一インターフェース(Uniform Interface)とは、情報の操作(取得、作成、更新、削除)は全てHTTPメソッド(GET、POST、PUT、DELETE)を利用すること。
Resourcefulルーティングとは、ひとつのコンテンツに対してこれらすべてが行えるルーティングという意味になります。前のセクションで示したような基本の書き方で一つ一つ記述してもいいのですが、それだと大変なので、Resourcefulルーティングを一行で書くことができます。
resources :articles
これだけの記述で以下のルーティングが使えるようになります。HTTPメソッドとパスの組み合わせによって振り分けるアクションが決定されます。ヘルパーの接頭辞については後述します。
メソッド | パス | アクション | ヘルパーの接頭辞 |
---|---|---|---|
GET | /articles | ArticlesController#index | articles |
GET | /articles/:id | ArticlesController#show | article |
GET | /articles/new | ArticlesController#new | new_article |
POST | /articles | ArticlesController#create | - |
GET | /articles/:id/edit | ArticlesController#edit | edit_article |
PUT/PATCH | /articles/:id | ArticlesController#update | - |
DELETE | /articles/:id | ArticlesController#destroy | - |
Resourcefulルーティングの引数名変更
Resourcefulルーティングデフォルトの引数名は:id
ですが、これを変更することができます。
resources :articles, param: :slug
上記のように引数名を:slug
に変更すると、以下のルーティングが使えるようになります。
メソッド | パス | アクション | ヘルパーの接頭辞 |
---|---|---|---|
GET | /articles | ArticlesController#index | articles |
GET | /articles/:slug | ArticlesController#show | article |
GET | /articles/new | ArticlesController#new | new_article |
POST | /articles | ArticlesController#create | - |
GET | /articles/:slug/edit | ArticlesController#edit | edit_article |
PUT/PATCH | /articles/:id | ArticlesController#update | - |
DELETE | /articles/:slug | ArticlesController#destroy | - |
複数のResourcefulルーティング
Resourcefulルーティングは一行で複数のコントローラーを書くこともできます。
resources :users, :sessions, :articles
入れ子のResourcefulルーティング
Resourcefulルーティングは入れ子にして書くこともできます。
resources :articles do
resources :comments
end
上記の例では、:articles
のルーティングに加え、以下のルーティングが使えるようになります。
メソッド | パス | アクション | ヘルパーの接頭辞 |
---|---|---|---|
GET | /articles/:article_id/comments | CommentsController#index | articles_comments |
GET | /articles/:article_id/comments/:id | CommentsController#show | article_comments |
GET | /articles/:article_id/comments/new | CommentsController#new | new_article_comments |
POST | /articles/:article_id/comments | CommentsController#create | - |
GET | /articles/:article_id/comments/:id/edit | CommentsController#edit | edit_article_comments |
PUT/PATCH | /articles/:article_id/comments/:id | CommentsController#update | - |
DELETE | /articles/:article_id/comments/:id | CommentsController#destroy | - |
Resourcefulルーティングの制限
Resourcefulルーティングで作成されるルーティングのうち、特定のルーティングを作成するにはonly
オプションを指定します。また、特定のルーティングを除外するにはexcept
オプションを指定します。以下の例では、作成されるルーティングはいずれもindex
とshow
のみとなります。
resources :articles, only: [:index, :show]
resources :articles, except: [:new, :create, :edit, :update, :destroy]
Resourcefulルーティングへの追加
Resourcefulルーティングで作成される7つのルーティング以外に別のルーティングを追加したい場合、以下のように記述します。
resources :articles do
collection do
get 'list', to: 'articles#list'
end
# 以下のようにも記述できる
# get 'list', to: 'articles#list', on: :collection
end
上記の例では、:articles
のルーティングに加え、以下のルーティングが使えるようになります。
メソッド | パス | アクション | ヘルパーの接頭辞 |
---|---|---|---|
GET | /articles/list | ArticlesController#list | list_articles |
引数付きのルーティングを追加したい場合、以下のように記述します。
resources :articles do
member do
get 'draft', to: 'article#draft'
end
# 以下のようにも記述できる
# get 'draft', to: 'article#draft', on: :member
end
上記の例では、:articles
のルーティングに加え、以下のルーティングが使えるようになります。
メソッド | パス | アクション | ヘルパーの接頭辞 |
---|---|---|---|
GET | /articles/:id/draft | ArticlesController#draft | draft_article |
ルーティングの名前空間
コントローラーを名前空間付きで作成している場合、ルーティングも名前空間付きで作成する必要があります。以下の例では、user/settings_controller.rb
のルーティングを作成しています。
namespace :user do
resources :settings
end
作成されるルーティングは以下の通りです。
メソッド | パス | アクション | ヘルパーの接頭辞 |
---|---|---|---|
GET | /user/settings | User::SettingsController#index | user_settings |
GET | /user/settings/:id | User::SettingsController#show | user_setting |
GET | /user/settings/new | User::SettingsController#new | new_user_setting |
POST | /user/settings | User::SettingsController#create | - |
GET | /user/settings/:id/edit | User::SettingsController#edit | edit_user_setting |
PUT/PATCH | /user/settings/:id | User::SettingsController#update | - |
DELETE | /user/settings/:id | User::SettingsController#destroy | - |
ルーティングのオプション
ルーティングの別名
ルーティングに別名をつけることができます。また、ルーティングに別名をつけるとヘルパーメソッドの接頭辞もそれにあわせて変更されます。以下の例では、ヘルパーメソッドはsignin_path
とsignin_url
となります。
get '/login', to: 'sessions#new', as: 'signin'
引数の制限
ルーティングに:id
などの引数が含まれる場合、有効とする引数の制限を行うことができます。以下の例では、:id
に1文字以上の数字のみを許可しています。
get 'articles/:id', to: 'articles#show', constraints: { id: /\d+/ }
レンダリング方法の指定
ブラウザのレンダリング方法を明示的に指定することができます。以下の例では、/feed
にアクセスするとRSS形式でレンダリングされます。
get '/feed', to: 'rss#index', defaults: { format: :rss }
ルーティング定義のモジュール化
カスタムdraw
メソッドを使うと、ルーティング定義をモジュール化して再利用しやすくできます。
例えば、特定のルーティング設定を別ファイルに分けて整理し、それをメインのroutes.rb
ファイルに読み込むことができます。これにより、ルーティングが複雑になっても管理しやすくなります。
まず、config/routes.rb
ファイルでdraw
メソッドを定義します。
config/routes.rb
Rails.application.routes.draw do
draw :admin
end
次に、config/routes/
ディレクトリを作成し、その中に分割するルーティング定義を含むファイルを作成します。例えば、config/routes/admin.rb
ファイルを作成します。
config/routes/admin.rb
Rails.application.routes.draw do
namespace :admin do
resources :users
resources :products
end
end
最後に、ルーティングファイルを読み込むためのカスタムdraw
メソッドを定義します。
config/initializers/routes_draw.rb
class ActionDispatch::Routing::Mapper
def draw(route)
instance_eval(File.read(Rails.root.join("config/routes/#{route}.rb")))
end
end
これにより、config/routes/admin.rb
ファイルの内容がconfig/routes.rb
ファイル内でdraw :admin
を呼び出すことによって読み込まれます。
ヘルパーメソッドの使用
ルーティングを作成すると、コントローラーやビューで使用できるヘルパーメソッドも自動作成されます。ヘルパーメソッドの名前は、ルーティングの接頭辞+_path
または_url
を繋げたものになります。
root 'statics#index'
# => root_path / root_url
get '/privacy', to: 'statics#privacy'
# => privacy_path / privacy_url
resources :articles
# => articles_path / articles_url
# => article_path(:id) / article_url(:id)
# => new_article_path(:id) / new_article_url(:id)
# => edit_article_path(:id) / edit_article_url(:id)
例えばarticles_path
は/articles
を返し、article_path(:id)
は/articles/:id
を返します。また、articles_url
は/articles
にホスト名を加えた値(完全なURL)を返します。
まとめ
ルーティングはビューを表示するURLだけを設定するわけではありません。create
やupdate
、destroy
といったアクションに専用のビューは存在しません。あるいはset_value
のようなAjax処理を実装している場合も同様です。コントローラーに存在するメソッド(アクション)には必ず対応するルーティングが存在している必要があります。
本記事を参考にして、ルーティングの書き方を覚えていただければと思います。