Rails 7.1 adds routes --unused option to detect extraneous routes

railsJuly 19, 2023Dotby Alkesh Ghorpade

Rails routes are essential for mapping URLs to specific actions, controllers, and views in your application. As your Rails app grows, more and more routes get added. However, some routes may become obsolete or irrelevant as your application evolves or undergoes refactoring. It is essential to keep your routes up to date to ensure efficient and accurate URL handling.

When adding a new controller to a Rails app, developers often add the resources directive to the routes file. This directive creates all seven default actions for the controller, even if the application only needs a few of them. The unused actions and routes will remain in the application unless the developer adds the except or only option to the resources directive.

Before Rails 7.1

No built-in method was available in Rails to detect unused routes before Rails 7.1 However, you could use a few third-party gems and scripts for this purpose.

  • traceroute gem: One option was to use the traceroute gem. This gem would print a list of all the routes in your application, and any unreachable action methods.

  • rake routes: Another option was to run the rake routes command and manually remove any routes you did not use.

  • Custom Script: You could also create a script to extract your application's unused routes.

unused_routes = {}

Rails.application.routes.routes.each do |r|
  name = r.requirements[:controller].to_s.camelize
  action = r.requirements[:action].to_s
  controller = "#{name}Controller"

  if Object.const_defined?(controller) && !controller.constantize.new.respond_to?(action)
    unless Dir.glob(Rails.root.join("app", "views", name.downcase, "#{action}.*")).any?
      unused_routes[controller] = [] if unused_routes[controller].nil?
      unused_routes[controller] << action
    end
  end
end

unused_routes

The script currently only checks if the view files are present or not. It must be modified to handle cases where the route is defined, but the controller is missing from the application. Using the Object.const_defined? method, you can check if the controller class exists. If the controller class does not exist, the route is considered to be unused.

In Rails 7.1

Rails made it easy to identify the unused route.

Rails 7.1 adds --unused option to rake routes command to identify extraneous routes. You must execute the below command on your terminal to get your application's list of unused routes.

> bin/rails routes --unused

# An example output of the above command will be as below:

Found 2 unused routes:

Prefix        Verb   URI                      Pattern    Controller#Action
get_token     GET    /get_token(.:format)                users#get_token
upgrade_token GET    /upgrade_token(.:format)            users#upgrade_token

If the application has no unused routes, the output will be:

> bin/rails routes --unused

No unused routes found.

You can also add the grep -g option to filter the unused routes result. If your application has a lot of unused routes and you want to verify if the particular action or the controller is unused, you can pass the -g option as below:

> bin/rails routes --unused -g upgrade_token

Found 1 unused route:

Prefix        Verb   URI                      Pattern    Controller#Action
upgrade_token GET    /upgrade_token(.:format)            users#upgrade_token

If there are no unused routes when filtered by the -g command, we see the following message:

> bin/rails routes --unused -g degrade_token

No unused routes found for this grep pattern.

You can filter unused routes by passing the controller name using the -c option. The unused routes command with the -c option works similarly to the -g command. If unused routes associated with that controller are present, they will be displayed else; no unused routes for this controller message get rendered.

> bin/rails routes --unused -c users

Found 2 unused routes:

Prefix        Verb   URI                      Pattern    Controller#Action
get_token     GET    /get_token(.:format)                users#get_token
upgrade_token GET    /upgrade_token(.:format)            users#upgrade_token


> bin/rails routes --unused -c random

No unused routes found for this controller.

This feature to detect unused routes in Rails will be very helpful for large and legacy applications. The feature will not significantly affect the boot time or performance of the application, but it will help to remove dead code.

This feature is handy when adding a new controller to an application. By detecting unused routes, you can ensure your application is clean and contains no dead code. This helps prevent confusion when working with large route files.

To know more about this feature, please refer to this PR.

Closing Remark

Could your team use some help with topics like this and others covered by ShakaCode's blog and open source? We specialize in optimizing Rails applications, especially those with advanced JavaScript frontends, like React. We can also help you optimize your CI processes with lower costs and faster, more reliable tests. Scraping web data and lowering infrastructure costs are two other areas of specialization. Feel free to reach out to ShakaCode's CEO, Justin Gordon, at justin@shakacode.com or schedule an appointment to discuss how ShakaCode can help your project!
Are you looking for a software development partner who can
develop modern, high-performance web apps and sites?
See what we've doneArrow right