⛷️

【Rails】ルーティングの色々な作成方法をざっくりまとめてみた

2021/07/17に公開

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

Image from Gyazo

4.ルーティングをグループ化する方法

代表的だと感じたルーティングのグループ化についてまとめてみました。

  • namespace
  • scope
  • scope module

使い方を以下で説明します。

  • namespace
    namespaceメソッドを用いてルーティングをグループ化すると、指定した名前空間名でルーティンングをグループ化することができます。ターミナルで確認すると、Prefix, URIパス, Controller#Actionに名前空間名が付与されていることが分かります。namespaceメソッドを用いたルーティングのグループ化は、名前空間によって識別されたコントローラのアクションを実行したい時に使用します。(例の場合、名前空間名をadminとしています。)
config/routes.rb
  namespace :admin do
    resources :boards
  end

Image from Gyazo

  • scope
    scopeメソッドを用いてルーティングをグループ化すると、パスのみグループ化できます。しかし、パスをグループ化しただけで、呼び出すコントローラやPrefixはルーティングをグループ化する前と同じです。
config/routes.rb
  scope :admin do
    resources :boards
  end

Image from Gyazo

  • scope module
    scopeメソッドとmoduleオプションを用いてルーティングをグループ化すると、呼び出すコントローラのアクションのみグループ化できます。Prefixやパスに関しては、ルーティングをグループ化する前と同じです。
config/routes.rb
  scope module: :admin do
    resources :boards
  end

Image from Gyazo

5.ルーティングのオプション

代表的だと感じたルーティングのオプションについてまとめてみました。

  • shallow
  • only
  • as
  • on

使い方を以下で説明します。

  • shallow
    shallowオプションはルーティングのネストの際に使います。shallowオプションを用いてルーティングのネストを作成すると、あるリソースに紐づくリソースのルーティングの内、コレクションルーティング(パスにidが含まれないルーティング)のみネストを行い、メンバールーティング(パスにidが含まれるルーティング)をネストしないようにできます。ターミナルの画面を見ると、あるリソースに紐づくリソースのコレクションルーティングのみがネストされてることが確認できます。ルーティングのネストの章で貼ったターミナル画面と比較してみると分かりやすいかもしれません。まとめると、shallowオプションを使うことで、深いネストを作らずに最小限の情報でリソースを特定できるルーティングを作成できます。
config/routes.rb
  resources :boards do
    resources :comments, shallow: true
  end

Image from Gyazo

  • only
    onlyオプションを使うことで、指定したアクションに対応するルーティングのみを作成できます。7つの基本アクションの一部のアクションしかコントローラに定義されていない場合に、onlyオプションを使うと無駄なルーティングの作成を防ぐことができます。そのため、コードの可読性が上がります。
config/routes.rb
  resource :profile, only: %i(show  edit update)

Image from Gyazo

  • as
    asオプションを使うことで、Prefix名を別名で上書きできます。asオプションのメリットはPrefix名が長い時に、短くできるところです。Prefix名を短くしたことによって、URLヘルパーのメソッド名を短くすることができます。
config/routes.rb
  post 'logout', to: 'user_sessions#destroy', as: :sorcery

Image from Gyazo

  • onオプション
    7つの基本アクション以外にアクションを1つコントローラに追加して、そのアクションを呼び出すルーティングを作成したいときにonオプションを使います。そのため、onオプションはresourcesメソッドと一緒に使います。コレクションルーティングを作成したい場合は、onオプションにcollectionを指定します。メンバールーティングを作成したい場合は、onオプションにmemeberを指定します。ターミナルを見ると、コントローラ内のあるアクションを呼び出すようルーティングが設定されていることが分かります。
config/routes.rb
  resources :boards do
    get 'bookmarks', on: :collection
  end

Image from Gyazo
1つのアクションではなく、複数のアクションをコントローラに追加した場合、そのアクションに対応した一つ一つのルーティングにonオプションを設定するのは面倒です。そのため、collectionメソッドまたはmemberメソッドを使ってまとめてルーティングを作成すると効率が良いです。

config/routes.rb
  resources :boards do
    collection do
      get 'bookmarks'
      get 'comments'
    end
  end

Image from Gyazo

6.終わり

ルーティングの作成方法についてまとめてみました。書いてて感じたのが、言語化するのが難しいということです。ルーティングはある程度理解したつもりでしたので、言語化も簡単だと思っていました。しかし、意外と難しく、曖昧な理解だったと気づきました。この記事が少しでも多くの人の役に立てば幸いです!

7.参考文献

https://qiita.com/senou/items/f1491e53450cb347606b
https://railsguides.jp/routing.html
https://pikawaka.com/rails/resources

Discussion