Railsのルーティングをdrawを使ってまとめる

# はじめに
gitlabのroutes.rbにて、`draw :api`の様に記載されているものを見つけ、とても便利だと思ったのでまとめます。

# draw

`draw :api`の様に記載すると、`config/routes/api.rb`に記載したルーティングを読みに行ってくれます。

例えば、namespaceごとにそれぞれ別のファイルにルーティングを記載することで、わかりやすくすることができます。

デフォルトで用意されているものではなく、gitlabのソースコードで独自に用意されていたものなので、少し下準備が必要になります。

# 下準備

`config/initializers`配下に`draw_routes.rb`ファイルを作成し、下記の内容を記載します。

ほとんど、gitlabのソースコードと同じです。

```ruby
module DrawRoute
  RoutesNotFound = Class.new(StandardError)

  def draw(routes_name)
    drawn_any = draw_route(routes_name)

    drawn_any || raise(RoutesNotFound, "Cannot find #{routes_name}")
  end

  def route_path(routes_name)
    Rails.root.join(routes_name)
  end

  def draw_route(routes_name)
    path = route_path("config/routes/#{routes_name}.rb")
    if File.exist?(path)
      instance_eval(File.read(path))
      true
    else
      false
    end
  end
end

ActionDispatch::Routing::Mapper.prepend DrawRoute
```

# 使用例
管理画面のroutesを切り出す

config/routes配下にadmin.rbを作成し、下記の様に記載

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

routes.rbに

```ruby
Rails.application.routes.draw do
  draw :admin
end
```

と記載することで、下記の様にroutesが作成されます。

```
                          admin_users GET    /admin/users(.:format)                                                                   admin/users#index
                                      POST   /admin/users(.:format)                                                                   admin/users#create
                       new_admin_user GET    /admin/users/new(.:format)                                                               admin/users#new
                      edit_admin_user GET    /admin/users/:id/edit(.:format)                                                          admin/users#edit
                           admin_user GET    /admin/users/:id(.:format)                                                               admin/users#show
                                      PATCH  /admin/users/:id(.:format)                                                               admin/users#update
                                      PUT    /admin/users/:id(.:format)                                                               admin/users#update
                                      DELETE /admin/users/:id(.:format)                                                               admin/users#destroy
```

# 使用例2

大きくなるモデルのroutesを切り出す。

例えば、`users_controller.rb`と`users/licences_controller.rb` `users/activates_controller.rb`がある場合に、user単位でフォルダにまとめます。

`config/routes/user.rb`

```ruby
resources :users do
  scope module: :users do
    resource :activates, only: %i[update destroy]
    resources :licences
  end
end
```

そして、routes.rbで読み込むことで

```ruby
Rails.application.routes.draw do
  draw :user
end
```

下記の様なルーティングが作成されます。

```
                       user_activates PATCH  /users/:user_id/activates(.:format)                                                      users/activates#update
                                      PUT    /users/:user_id/activates(.:format)                                                      users/activates#update
                                      DELETE /users/:user_id/activates(.:format)                                                      users/activates#destroy
                             licences GET    /users/licences(.:format)                                                                users/licences#index
                                      POST   /users/licences(.:format)                                                                users/licences#create
                          new_licence GET    /users/licences/new(.:format)                                                            users/licences#new
                         edit_licence GET    /users/licences/:id/edit(.:format)                                                       users/licences#edit
                              licence GET    /users/licences/:id(.:format)                                                            users/licences#show
                                      PATCH  /users/licences/:id(.:format)                                                            users/licences#update
                                      PUT    /users/licences/:id(.:format)                                                            users/licences#update
                                      DELETE /users/licences/:id(.:format)                                                            users/licences#destroy
                                users GET    /users(.:format)                                                                         users#index
```

# 終わりに

アプリが大きくなるにつれ、routes.rbがカオスになることがあると思うので、drawを使って良い感じにファイルを分けることで、すっきりしそうです。