← All Articles

How to split Rails routes.rb into multiple smaller files

Over time as your Rails application grows, you end up with a very lengthy config/routes.rb file, eg 


# config/routes.rb
Rails.application.routes.draw do

  mount RailsAdmin::Engine => '/admin', as: 'rails_admin'

  devise_for :users

  namespace :api, defaults: { format: :json } do
    namespace :v1 do
      get 'subjects' => 'subjects#index'
      get 'users/:id' => 'users#show'
      # -- snip -- #
    end
  end

  namespace :admin do
    resources :users do
      member do
        get :friends
      end
    end
    resources :products
    # -- snip --#
  end

  root to: 'visitors#index'
end

As this gets harder to manage, one handy trick I use is to split these different sections into their own files by monkey-patching the Routing mapper like so:


# config/routes.rb
class ActionDispatch::Routing::Mapper
  def draw(routes_name)
    instance_eval(File.read(Rails.root.join("config/routes/#{routes_name}.rb")))
  end
end

Rails.application.routes.draw do
  mount RailsAdmin::Engine => '/admin', as: 'rails_admin'

  devise_for :users

  draw :api
  draw :admin
  root to: 'visitors#index'
end

That little draw method allows you to place your API and Admin routes into separate files like this:


# config/routes/api.rb
namespace :api, defaults: { format: :json } do
  namespace :v1 do
    get 'subjects' => 'subjects#index'
    get 'users/:id' => 'users#show'
    # -- snip -- #
  end
end


# config/routes/admin.rb
namespace :admin do
  resources :users do
    member do
      get :friends
    end
  end
  resources :products
  # -- snip --#
end

This was previously done a different way in Rails 3, but after a lengthy discussion it was eventually reverted out in Rails 4. Thankfully the little method I described here works for both Rails 3 and 4.

Made with JoyBird