How to organize a routes.rb file in Rails

If you have a small Ruby on Rails application, you probably don’t have much need to organize your routes.rb file. However if your project is large, you probably have a somewhat complicated, and quite frankly, messy routes file. Sometimes its hard to really understand where your routes are, especially when you are working with hundreds of lines of routes. I had such an issue in a recent project I was working on.

The project has multiple contexts within it, and each on of them has their own set of routes. These were all smushed into the main routes.rb file along with the normal base routes. What I wanted to do was create multiple routes files under a config/routes folder and split them up there to make them more manageable. Here is an example of how to split them up:

# config/routes.rb
Rails.application.routes.draw do
  # Some base routes here
  resources :pages


  extend AdminRoutes
  extend UserRoutes
  extend OrganizationRoutes
end

As you can see, we have a basic routes file, however you will notice that there are a few extend Class directives in there. These will load in the corresponding class file, that I will have stored in the config/routes folder. Here is an example of what one of those files looks like.

# config/routes/admin_routes.rb

module AdminRoutes
  def self.extended(router)
    router.instance_exec do
      authenticate :user, lambda { |u| u.admin? } do
        mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
        mount Sidekiq::Web => '/sidekiq'
      end
    end
  end
end

I will show you one more, since the AdminRoutes file is mostly just the entry point for some mounted Rails Engines, and not normal resources

# config/routes/user_routes.rb

module UserRoutes
  def self.extended(router)
    router.instance_exec do

      authenticated :user do
        root to: "dashboard#show", as: :authenticated_root
      end

      devise_for :users,
        :skip => [:registrations],
        :controllers => { :invitations => 'user/invitations' }
      as :user do
        get '/user/new' => 'user/registrations#new', as: 'new_user_registration'
        post '/user' => 'user/registrations#create', as: 'user_registration'

        get 'user/edit' => 'user/registrations#edit', :as => 'edit_user_registration'
        put ':id' => 'user/registrations#update', :as => 'registration'

        delete '' => 'user/registrations#destroy'
      end

    end
  end
end

The last thing we need to do, is make sure that the new config/routes folder gets picked up by rails. Add the following line to your config/application.rb file

config.autoload_paths += %W(#{config.root}/config/routes)

Hopefully these examples help you with splitting up a large routes.rb file into smaller, more manageable pieces. Let me know in the comments if this helps, or you have any issues getting this to work.

Rails route helpers – route_url vs route_path

If you weren’t already aware of this, there IS a difference between using route_url and route_path. Here are what they return:

<%= posts_url %>  # => http://localhost:3000/posts
<%= posts_path %> # => /posts

As a general rule of thumb, you would want to use posts_url in your controllers, and posts_path in your views.