【Ruby on Rails】namespace と scope の違いって何？

# はじめに

こんにちは、エンジニア3年目の嶋田です。
まずは、この記事を開いていただきありがとうございます！

Railsアプリケーションを開発していると、ルーティングの設計がとても大切だと感じることが増えてきました。
同時に自分の理解が浅いことも実感しています…
そこで今回はこの記事でアウトプットをして理解を深めていきたいです。

よろしくお願いします！

# 目次

- [namespaceとscopeの違い](#namespaceとscopeの違い)
  - [namespaceの特徴](#namespaceの特徴)
  - [scopeの特徴](#scopeの特徴)
- [namespaceの使い方](#namespaceの使い方)
  - [基本的な使い方](#基本的な使い方)
  - [ネストしたリソース](#ネストしたリソース)
- [scopeの使い方](#scopeの使い方)
  - [基本的な使い方](#基本的な使い方)
  - [パスとパラメータのカスタマイズ](#パスとパラメータのカスタマイズ)
- [使い分けのポイント](#使い分けのポイント)
- [カスタムルートの利用](#カスタムルートの利用)
  - [scope moduleの利用](#scope-moduleの利用)
  - [shallowオプションの利用](#shallowオプションの利用)
- [最後に](#最後に)
- [参考文献](#参考文献)

# namespaceとscopeの違い

Railsのルーティングでは、`namespace` と `scope` を使用することでルートを整理することができます。これらの機能は似ていますが、それぞれ異なる目的と使い方があります。

## namespace

`namespace` はコントローラーのモジュールをグループ化するために使用されます。`namespace`を使うと、自動的にURLパスとコントローラーの名前空間が設定されます。

例えば、以下のように設定します。

```ruby
namespace :admin do
  resources :users
end
```

この設定により、`/admin/users` というパスが生成され、対応するコントローラーは `Admin::UsersController` になります。

## scope

`scope` はURLパスや名前空間をカスタマイズするために使用されます。`scope`を使うと、URLパスだけを変更することができ、コントローラーの名前空間を変更しません。

例えば、以下のように設定します。

```ruby
scope '/admin' do
  resources :users
end
```

この設定により、`/admin/users`というパスが生成されますが、対応するコントローラーは`UsersController`のままです。

# namespaceの使い方

`namespace`を使用すると、関連するコントローラーをモジュール内にグループ化し、名前空間付きのURLを生成できます。

## 基本的な使い方

例えば、管理者用のコントローラーをまとめるために`namespace`を使用します。

```ruby
namespace :admin do
  resources :products
end
```

これにより、以下のようなルーティングが生成されます。

- `GET /admin/products` -> `Admin::ProductsController#index`
- `GET /admin/products/:id` -> `Admin::ProductsController#show`
- `POST /admin/products` -> `Admin::ProductsController#create`

## ネストしたリソース

`namespace`はネストしたリソースにも使用できます。

```ruby
namespace :admin do
  resources :products do
    resources :reviews
  end
end
```

これにより、`/admin/products/:product_id/reviews` のようなパスが生成されます。

# scopeの使い方

`scope`を使用すると、URLパスをカスタマイズしつつ、コントローラーの名前空間は変更しません。

## 基本的な使い方

例えば、URLパスだけを変更したい場合に`scope`を使用します。

```ruby
scope '/admin' do
  resources :products
end
```

これにより、以下のようなルーティングが生成されますが、コントローラーは変更されません。

- `GET /admin/products` -> `ProductsController#index`
- `GET /admin/products/:id` -> `ProductsController#show`
- `POST /admin/products` -> `ProductsController#create`

## パスとパラメータのカスタマイズ

`scope`を使用して、パスとパラメータをカスタマイズすることもできます。

```ruby
scope '/admin', as: 'admin' do
  resources :products, path: 'items'
end
```

これにより、以下のようなルーティングが生成されます。

- `GET /admin/items` -> `ProductsController#index`
- `GET /admin/items/:id` -> `ProductsController#show`
- `POST /admin/items` -> `ProductsController#create`

# 使い分けのポイント

`namespace` と `scope` の使い分けは、以下のポイントを考慮すると良いでしょう。

- **モジュールの整理が必要な場合**: コントローラーをモジュールで整理したい場合は`namespace`を使用します。
- **URLパスだけを変更したい場合**: URLパスをカスタマイズしたいが、コントローラーは変更したくない場合は`scope`を使用します。

# カスタムルートの利用

`namespace` と `scope` 以外にも、Railsのルーティングでは `scope module` や `shallow` オプションを使用して、さらに柔軟にルーティングを設定できます。

## scope moduleの利用

`scope module` を使用すると、URLパスを変更せずにコントローラーの名前空間を変更できます。

例えば、以下のように設定します。

```ruby
scope module: 'admin' do
  resources :products
end
```

この設定により、`/products` というパスが生成され、対応するコントローラーは `Admin::ProductsController` になります。

## shallowオプションの利用

`shallow` オプションを使用すると、ネストしたリソースのルートを簡略化できます。これにより、深くネストされたリソースのルーティングが見やすくなります。

例えば、以下のように設定します。

```ruby
resources :products do
  resources :reviews, shallow: true
end
```

これにより、以下のようなルーティングが生成されます。

- `GET /products/:product_id/reviews` -> `ReviewsController#index`
- `GET /reviews/:id` -> `ReviewsController#show`
- `POST /products/:product_id/reviews` -> `ReviewsController#create`
- `PATCH/PUT /reviews/:id` -> `ReviewsController#update`
- `DELETE /reviews/:id` -> `ReviewsController#destroy`

# 最後に

最後までお読みいただきありがとうございました。ルーティングの設計はRailsアプリケーションの重要な部分です。
私自身まだまだ理解が足りず、難しいなと感じている今日この頃です…😅
この記事が少しでも皆さんの助けになれば幸いです。引き続き楽しく学んでいきましょう！

# 参考文献

- [RailsのRouting](https://railsguides.jp/routing.html)