はじめに
ルーティングって市販の教材とかだと基本的なことしか載っていなかったり「するけど、
実務だと市販教材には載っていない使い方とかよくあったりします。
そんなルーティングの使い方を紹介していきます。
rails routesコマンドを使ってルーティングの確認
アプリケーション内で定義されている全てのルートが一覧表示されます。
これには、HTTPメソッド、URLパス、コントローラーとアクション
、そしてそれぞれのルートに対するヘルパーメソッドなどのがわかるので、アプリケーション全体のURL構造やルーティング設定を確認できます。
例えばgrep機能も使えたりします。
rails routes |grep api/v1
これはルーティングでapi/v1という文字列を含む行だけを抽出して表示するためのコマンドです。
api_v1_articles GET /api/v1/articles(.:format) api/v1/articles#index
POST /api/v1/articles(.:format) api/v1/articles#create
api_v1_article GET /api/v1/articles/:id(.:format) api/v1/articles#show
PATCH /api/v1/articles/:id(.:format) api/v1/articles#update
PUT /api/v1/articles/:id(.:format) api/v1/articles#update
DELETE /api/v1/articles/:id(.:format) api/v1/articles#destroy
みたいな感じで表示されたりします。
root
最初にユーザーがアプリケーションにアクセスしたときに表示されるページを指定できます。
ユーザーが最初にアプリケーションにアクセスしたとき、WelcomeControllerのindexアクションを表示する
という意味で、WelcomeControllerは例えば「ようこそ!」と書かれたページを表示する役割を果たしたりします。
Rails.application.routes.draw do
root to: 'welcome#index'
#中略
end
resourcesについて
RailsにおいてRESTfulなルーティングを簡単に設定するのに役立ちます。
アプリケーションには様々なデータや情報があります。
例えば、X(旧Twitter)なら投稿、ユーザー、コメントなどが考えられ、
これらのデータを取り扱うときに、それぞれのデータに対して行える操作(表示、作成、更新、削除など)があります。
Railsのresourcesを使うと、これらのデータに対してRESTfulなアクションを簡単に作れます。
例えば、投稿に関するresourcesを設定すると、投稿一覧を表示するページ、新しい投稿を作成するページ、特定の投稿を表示するページ(実際はないですが)などが自動的に作られます。
Rails.application.routes.draw do
resources :posts
end
URL | 説明 |
---|---|
GET /posts: | 投稿一覧を表示するページ |
GET /posts/new: | 新しい投稿を作成するページ |
GET /posts/:id | 特定の投稿を表示するページ(:idは記事の識別子) |
POST /posts: | 新しい記事を作成するアクション |
PATCH /posts/:id | 特定の記事を更新するアクション |
DELETE /posts/:id | 特定の記事を削除するアクション |
簡単に言えば、resourcesはアプリケーションでは、さまざまなデータに対して
標準的なアクションを定義する手間を省いてくれる便利な機能です。
only
他にもこんな使い方をしたことがあります。
namespace :users do
resources :posts, only: [:index]
end
namespaceはこの後話します。onlyを使ったことがあります。
:postsはリソースの名前で、PostsControllerに対応することが期待され、
only: [:index]
は、このリソースに対してどのアクションを許可するかを指定します。
indexアクションのみを有効にし、ユーザーが投稿の一覧を表示するためのものです。
結果として、GET /users/posts に対しては、PostsControllerのindexアクションが呼び出されます。
コントローラー内のアクションで使うルーティング
Rails.application.routes.draw do
get "static_pages/home"
get "static_pages/help"
root "application#hello"
end
引用 https://railstutorial.jp/chapters/static_pages?version=7.0#aside-undoing_things
get "static_pages/home"
とありますが、
このルールは、/static_pages/homeというURLに対するリクエストを、
StaticPagesコントローラのhomeアクションと結びつけています。
今回はgetと書かれているので、GETリクエストを受け取ったときに
対応するアクションを結びつけています。
チュートリアルだと
https://中略/static_pages/home
のURLで表示されます。
⚫︎補足
GETとPOSTの説明はこの動画の解説が個人的にわかりやすかったです。
Laravelとなっていますが、Railsと似ているので問題ないかと思います。
namespace
最初から下の様にバージョンで名前空間を作成しておくことで今後のAPIのバージョン管理が簡単になります。
namespaceは、指定した名前空間にルーティングをまとめるためのもので、
この場合、:usersという名前空間が指定されています
名前空間を使用することで、同じ名前のコントローラーが別の名前空間内で存在しても競合することなく使えるようにします。
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :articles
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
end
end
scope
特定のURLに共通の言葉やディレクトリを追加できます。
例えば/adminというURLにアクセスすると、それより後のURLは/adminになります。
これは管理者向けのページにアクセスするときに使います。
scope '/admin' do
resources :users
end
module
の使い方も説明しておきます。
それぞれ異なる機能を組み合わせてルーティングを整理し、モジュール化するためのものです。
特定のページや機能がどのグループ(モジュール)に属するかを指定でき、
大きなプロジェクトでコードを整理するのに使います。
例えば、/admin/productsといったURLは、商品情報に関する管理者用のページにアクセスする場合に使います。
scope '/admin', module: 'admin' do
resources :products
end
コントローラーが所属するモジュールを指定でき、
/admin/productsにアクセスすると、Admin::ProductsControllerが呼び出されます。
collection
特定のリソース全体に関連するアクションを指定するために使います。
例えばプログラミングスクールのウェブアプリがあるとするとユーザー(生徒)がたくさんいて、
それぞれが日報、質問、プルリク、レビューなどの情報を持っているとします。
これらの情報は特定のユーザーに紐づいているのではなく、全てのユーザーに関連しています。
collectionを使って、ユーザー全体に関連するアクションを指定できます。
以下の例では、ユーザー全体の日報、プルリクエスト、質問、レビュー、コメントにアクセスするためのURLを定義します。
resources :users, param: :student_id,only: [:index, :show]
collection do
resources :daily_reports, only: [:index]
resources :pull_requests, only: [:index]
resources :questions, only: [:index]
resources :review, only: [:index]
resources :comment, only: [:index]
end
end
UsersControllerに対して基本的なアクション(一覧と詳細)と、
ユーザー全体に関連するアクション(日報、プルリクエスト、質問、レビュー、コメントの一覧)を定義しています。
REST |
---|
GET /users:ユーザー一覧を表示するページ(indexアクション) |
GET /users/:student_id: 特定のユーザーの詳細を表示するページ(showアクション) |
GET /users/daily_reports: 全てのユーザーの日報一覧を表示するページ |
GET /users/pull_request: 全てのユーザーのプルリクエスト一覧を表示するページ |
GET /users/questions: 全てのユーザーの質問一覧を表示するページ |
GET /users/review: 全てのユーザーのレビュー一覧を表示するページ |
GET /users/comment: 全てのユーザーのコメント一覧を表示するページ |
実務でこんな使い方をした
実際に実務でこんな使い方もしたというのもお伝えします。
Rails.application.routes.draw do
root to: 'Welcome#home'
namespace :api do
namespace :v1 do
draw :student
draw :issue
draw :web
end
end
end
ここでdrawを使って別のroutesディレクトリの中のweb.rbにnamespaceを追加しました。
URLは以下のようにしました。
http://localhost:3000/api/v1/web/users/posts
上のコードでdraw :webを消したらエラーが出てしまいました。上のroute.rbで定義して
routesファイルの中にweb.rbを作ったりしました。studentやissueも同じ感じです。
namespace :web do
#中略
namespace :users do
#中略
end
resources :users, #中略
#中略
end
end
end
資料
ChatGPT参照。