🤿

【Rails】Routing:shallowオプション

2023/08/02に公開

shallowオプションとは

ルーティング設定でネストしたリソース(resources)のルートを、よりシンプルにするためのオプション。

具体例

例えば以下のテーブルがあるとする。

  1. users (ユーザー情報)
  2. posts (投稿)
  3. comments (コメント)

通常のネストしたルーティングを使った場合

Rails.application.routes.draw do
  resources :users do
    resources :posts do
      resources :comments
    end
  end
end

このルーティング設定では、以下のようなURLになる。

アクション URL
posts#show /users/:user_id/posts/:id
comments#show /users/:user_id/posts/:post_id/comments/:id

上記のように、commentsリソースはuserspostsにネストされているため、親リソースであるユーザー情報と投稿のIDが必要になる。

shallowオプションを使ったルーティング

Rails.application.routes.draw do
  resources :users do
    resources :posts, shallow: true do
      resources :comments
    end
  end
end

shallow: trueを指定することで、postsリソースはusersの下にネストされなくなる。これにより、postsのURLは親リソースを含めずシンプルになる。

アクション URL
posts#show /posts/:id

commentsリソースもpostsの下にネストされているが、postsのIDが必要なくなったため、URLが短くなる。

アクション URL
comments#show /comments/:id

このように、shallowオプションを使うことでルーティングがわかりやすくなり、短くすることができる。

メリット & デメリット

メリット

  • ルーティングの可読性がよくなる。
  • ネストしたリソースにアクセスする際に、親リソースのIDが不要になり、URLが短くなる。

デメリット

  • RESTfulでなくなる。(URLの一貫性がなくなる)
  • ネストしているのかがURLからじゃわからない。
  • ヘルパーメソッドのフォームの書き方が一貫しない。

具体例は以下の通り。
commentsコントローラのnewアクションとeditアクションのフォームの違い。

  1. comments#newアクションのフォーム
    newアクションでは、URLに親リソースのID(post_id)が含むので、新しいコメントを投稿する際に、どの投稿に対するコメントかを特定するための親リソースのIDをフォームに含める必要がある。
<%= form_with(model: [@post, @comment]) do |form| %>
  <!-- フォームの内容 -->
<% end %>
  1. comments#editアクションのフォーム
    editアクションでは、URLに親リソースのIDが含まれないため、既存のコメントを編集する際には、親リソースのIDをフォームに含める必要がない。
<%= form_with(model: @comment) do |form| %>
  <!-- フォームの内容 -->
<% end %>

shallowオプションを使わなければ、新規作成フォームと編集フォームのフォームは以下の通り同じになる。

<%= form_with(model: [@user, @post, @comment]) do |form| %>
  <!-- フォームの内容 -->
<% end %>

個人的には、デメリットの方が大きく、あまり多用できるものではないと感じた。

Discussion