Recently, my former colleague wrote an excellent blogpost based on DHH solution about splitting routes.rb into smaller parts. It’s a coincidence that I introduced a similar solution in my current project some time ago. I find this approach extremely useful, especially when you have to deal with a big domain and many different contexts that can be separated by directories with corresponding routes’ files.

Problems

With the original solution I had two small issues that I wanted to solve.

1. Each time when I added a new domain concept and I wanted to expose new API endpoints, I had to do it in two files — not only create a specific file in config/routes directory, but also remember to modify main routes.rb file to draw a new endpoint. Right now I just load everything like that:

And my particular file for routes may look like as follows:

2. The next problem I had, was with automatically reloading routes while a sever was running. Any time I added or even modified something inside routes directory, changes weren’t applied until I restarted my server. To solve that, I created a simple middleware that can reload routes when some change appears:

I used ActiveSupport::FileUpdateChecker for observing any change in config/routes/* directory. On every request, when there was an update, rails routes are being reloaded. You have to only enable that middleware in application.rb file:

require_relative '../lib/rails_routes_reloader'

config.middleware.use RailsRoutesReloader

Summary

Some may say that instance_eval is not the best solution. That migh be righ unless you can control it by yourself. In that case, the code is not in a part of your business logic, but only of the configuration, so I think it is acceptable to use it there.

Moreover, if someone claims that unmanageable routes mean unmanageable domain, that can be true from one perspective, but on the other hand, splitting routes into smaller pieces can be just a matter of organizing your code in a different, cleaner way.