[RUBY] Organize Rails routing using draw

Introduction

In routes.rb of gitlab, I found something like draw: api and found it very useful, so I will summarize it.

draw

If you write something like draw: api, it will read the routes described in config/routes/api.rb.

For example, you can make it easier to understand by writing the routing in a separate file for each namespace.

It is not prepared by default, but it was prepared independently in the source code of gitlab, so some preparation is required.

Preparation

Create a draw_routes.rb file under config/initializers and describe the following contents.

It's almost the same as the gitlab source code.

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

Example of use

Cut out the routes of the management screen

Create admin.rb under config/routes and describe as below

namespace :admin do
  resources :users
end

in routes.rb

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

By describing, routes will be created as shown below.

                          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

Usage example 2

Cut out the routes of the larger model.

For example, if you have users_controller.rb and users/licenses_controller.rb users/activates_controller.rb, group them into folders for each user.

config/routes/user.rb

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

And by reading in routes.rb

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

The following routing will be created.

                       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

At the end

As the app grows, routes.rb can become chaotic, so using draw to nicely separate the files seems to be neat.

Recommended Posts

Organize Rails routing using draw
About Rails routing
Rails Routing Basics
Rails 6.0 Routing Summary
Catch Rails Routing Error
[Rails] devise-related routing summary
[Note] Rails3 routing confirmation
Understand Rails "shallow" routing
[Rails] Complete routing settings
Search function using [rails] ransack
Try using view_component with rails
[Rails] Save images using carrierwave
Japaneseize using i18n with Rails
[Rails] Japanese localization using rails-i18n
[Rails] Test code using Rspec
Ajax bookmark function using Rails
Rails routing controller view relationship
Error when using rails capybara
[Rails] Try using Faraday middleware
Detailed tips when using Rails
How to write Rails routing
[Rails 6] Star-shaped review using Raty.js
Rails singular resource routing by resource
Get PV (views) using Impressionist ~ Rails
[Rails] Tag management function (using acts-as-taggable-on)
[Rails 6] API development using GraphQL (Query)
[Rails] Summary of complicated routing configurations
Set Rails routing other than id
Ruby On Rails devise routing conflict
[Rails 6] destroy using the resources method
[Rails] Status update using Rake task
[Rails] Reflection to db using seeds.rb