⛷️
【Rails】ルーティングの色々な作成方法をざっくりまとめてみた
1.この記事をなぜ書いたか
Railsのルーティングには様々な作成方法が存在します。そのため、書き方を頻繁に忘れてしまい、その都度Qiitaの記事にお世話になっています笑。しかし、何度見ても書き方を忘れてしまうので、自分でアウトプットして記憶に定着させようと思い、この記事を書きました。
間違いがある場合、コメント頂けると嬉しいです。
2.代表的なルーティングの作成方法
代表的だと感じたルーティングの作成方法についてまとめてみました。
- root
- get
- post
- resources
- resource
使い方を以下で説明します。
- root
rootメソッドを用いてルーティングを作成すると、ルート(/)でサーバーにアクセスした際に、rootメソッドで指定したコントローラのアクションが実行されます。
config/routes.rb
root to: 'static_pages#top'
ターミナル
Prefix Verb URI Pattern Controller#Action
root GET / static_pages#top
- get
getメソッドを用いてルーティングを作成すると、getメソッドで指定したパスでサーバーにGETメソッドのHTTPリクエストが来た際に、getメソッドで指定したコントローラのアクションが実行されます。サーバーからのファイル取得のみの場合に、getメソッドを用いてルーティングを作成します。
config/routes.rb
get 'login', to: 'user_sessions#new'
ターミナル
Prefix Verb URI Pattern Controller#Action
login GET /login(.:format) user_sessions#new
- post
postメソッドを用いてルーティングを作成すると、postメソッドで指定したパスでサーバーにPOSTメソッドのHTTPリクエストが来た際に、postメソッドで指定したコントローラのアクションが実行されます。サーバーにデータを送信する場合に、postメソッドを用いてルーティングを作成します。
config/routes.rb
post 'login', to: "user_sessions#create"
ターミナル
Prefix Verb URI Pattern Controller#Action
login POST /login(.:format) user_sessions#create
- resources
resourcesメソッドを用いてルーティングを作成すると、WebアプリケーションのCRUD機能を実装するために必要なルーティングを全て作成することができます。resourcesメソッドとonlyオプションを組み合わせて必要なルーティングのみ作成すると、コードの可読性と効率が良いです。
config/routes.rb
resources :users
ターミナル
Prefix Verb URI Pattern Controller#Action
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
- resource
resourceメソッドを用いてルーティングを作成すると、以下のようなルーティングが作成されます(indexアクションへのルーティングは作成されません)。resoruceメソッドを使ってルーティングを作成するメリットは、パスにidパラメータが含まれないことです。他のユーザーの投稿や自分自身の投稿へアクセスするパスには、アクセスしたい投稿を識別するために、アクセスしたい投稿自体のidをパスに含める必要があります。しかし、自分のプロフィール編集画面等へアクセスするパスにidパラメータを含める必要はありません。理由は、自分のプロフィール編集画面は1つしか存在しないので、プロフィール編集画面を識別するidが必要ないからです。resourceメソッドは、あるユーザーから見て、リソースが1つしか存在しない時に使うと良さそうです。
config/routes.rb
resource :user
ターミナル
Prefix Verb URI Pattern Controller#Action
new_user GET /user/new(.:format) users#new
edit_user GET /user/edit(.:format) users#edit
user GET /user(.:format) users#show
PATCH /user(.:format) users#update
PUT /user(.:format) users#update
DELETE /user(.:format) users#destroy
POST /user(.:format) users#create
3.ルーティングのネストの作成方法
代表的だと感じたルーティングのネストについてまとめてみました。
- resources
使い方を以下で説明します。
(以下の例では、ネスト内部のルーティングをresourcesメソッドを用いて作成してますが、getメソッドでもpostメソッドでも大丈夫です。)
- resources
resourcesメソッドを用いてルーティングのネストを作成すると、あるリソースのルーティングと、あるリソースに紐づくリソースのルーティングを作成できます。下の例だと、投稿のルーティングと、投稿に紐づくコメントのルーティングが作成されています。あるリソースに紐づくリソースのルーティングが示すパスには、あるリソースのidと、紐づいたリソースのidが含まれています。パスに含まれた2つのidパラメータを用いることで、コントローラ内でリソースに外部キーを設定することが可能になります。外部キーを設定可能になることが、resourcesメソッドを用いたルーティングのネストを利用するメリットだと個人的に感じています。外部キーを設定することで、アソシエーションメソッドを使って、あるリソースに紐づくリソースの取得が可能になるからです。
(事前に、モデル間のアソシエーションを設定することで、アソシエーションメソッドが使えるようになります。)
config/routes.rb
resources :boards do
resources :comments
end
4.ルーティングをグループ化する方法
代表的だと感じたルーティングのグループ化についてまとめてみました。
- namespace
- scope
- scope module
使い方を以下で説明します。
- namespace
namespaceメソッドを用いてルーティングをグループ化すると、指定した名前空間名でルーティンングをグループ化することができます。ターミナルで確認すると、Prefix, URIパス, Controller#Actionに名前空間名が付与されていることが分かります。namespaceメソッドを用いたルーティングのグループ化は、名前空間によって識別されたコントローラのアクションを実行したい時に使用します。(例の場合、名前空間名をadminとしています。)
config/routes.rb
namespace :admin do
resources :boards
end
- scope
scopeメソッドを用いてルーティングをグループ化すると、パスのみグループ化できます。しかし、パスをグループ化しただけで、呼び出すコントローラやPrefixはルーティングをグループ化する前と同じです。
config/routes.rb
scope :admin do
resources :boards
end
- scope module
scopeメソッドとmoduleオプションを用いてルーティングをグループ化すると、呼び出すコントローラのアクションのみグループ化できます。Prefixやパスに関しては、ルーティングをグループ化する前と同じです。
config/routes.rb
scope module: :admin do
resources :boards
end
5.ルーティングのオプション
代表的だと感じたルーティングのオプションについてまとめてみました。
- shallow
- only
- as
- on
使い方を以下で説明します。
- shallow
shallowオプションはルーティングのネストの際に使います。shallowオプションを用いてルーティングのネストを作成すると、あるリソースに紐づくリソースのルーティングの内、コレクションルーティング(パスにidが含まれないルーティング)のみネストを行い、メンバールーティング(パスにidが含まれるルーティング)をネストしないようにできます。ターミナルの画面を見ると、あるリソースに紐づくリソースのコレクションルーティングのみがネストされてることが確認できます。ルーティングのネストの章で貼ったターミナル画面と比較してみると分かりやすいかもしれません。まとめると、shallowオプションを使うことで、深いネストを作らずに最小限の情報でリソースを特定できるルーティングを作成できます。
config/routes.rb
resources :boards do
resources :comments, shallow: true
end
- only
onlyオプションを使うことで、指定したアクションに対応するルーティングのみを作成できます。7つの基本アクションの一部のアクションしかコントローラに定義されていない場合に、onlyオプションを使うと無駄なルーティングの作成を防ぐことができます。そのため、コードの可読性が上がります。
config/routes.rb
resource :profile, only: %i(show edit update)
- as
asオプションを使うことで、Prefix名を別名で上書きできます。asオプションのメリットはPrefix名が長い時に、短くできるところです。Prefix名を短くしたことによって、URLヘルパーのメソッド名を短くすることができます。
config/routes.rb
post 'logout', to: 'user_sessions#destroy', as: :sorcery
- onオプション
7つの基本アクション以外にアクションを1つコントローラに追加して、そのアクションを呼び出すルーティングを作成したいときにonオプションを使います。そのため、onオプションはresourcesメソッドと一緒に使います。コレクションルーティングを作成したい場合は、onオプションにcollectionを指定します。メンバールーティングを作成したい場合は、onオプションにmemeberを指定します。ターミナルを見ると、コントローラ内のあるアクションを呼び出すようルーティングが設定されていることが分かります。
config/routes.rb
resources :boards do
get 'bookmarks', on: :collection
end
1つのアクションではなく、複数のアクションをコントローラに追加した場合、そのアクションに対応した一つ一つのルーティングにonオプションを設定するのは面倒です。そのため、collectionメソッドまたはmemberメソッドを使ってまとめてルーティングを作成すると効率が良いです。
config/routes.rb
resources :boards do
collection do
get 'bookmarks'
get 'comments'
end
end
6.終わり
ルーティングの作成方法についてまとめてみました。書いてて感じたのが、言語化するのが難しいということです。ルーティングはある程度理解したつもりでしたので、言語化も簡単だと思っていました。しかし、意外と難しく、曖昧な理解だったと気づきました。この記事が少しでも多くの人の役に立てば幸いです!
7.参考文献
Discussion