Custom Routes in Rails
In the life of almost all Rails applications, comes the moment where custom routes are needed. Usually, the custom routes are just convenience methods like these:
def post_path(post)
date_post_path post.date_slug, post.slug
end
def product_url
date_post_url post.date_slug, post.slug
end
In this way, you decouple the route generation from your objects. Also, if you are doing some system route update and you want to keep the old routes around - this is the way.
Usually, I create a module CustomPaths
and put those methods there. But in recent years, Rails.application.routes.url_helpers
is showing up in more and more places like - background jobs, presenters, serializers and so. This complicates things.
At Product Hunt we needed some custom paths. So, me and Mike Coutermarsh created the following object:
# => routes.rb
module Routes
# Simple `extend self` won't work here,
# due to the way Rails implement `url_helpers`
class << self
include Rails.application.routes.url_helpers
include Routes::CustomPaths
end
include Rails.application.routes.url_helpers
include Routes::CustomPaths
def default_url_options
Rails.application.routes.default_url_options
end
end
# => routes/custom_paths.rb
module Routes
module CustomPaths
# ... all your custom route methods
end
end
It behaves the same way as Rails.application.routes.url_helpers
plus the custom routes.
# in can be called directly
Routes.root_path
Routes.product_path(product)
# or included in another object
class ObjectWhoNeedsRoutes
include Routes
end
ObjectWhoNeedsRoutes.new.root_path
ObjectWhoNeedsRoutes.new.product_path
I added Routes
to my toolbox with install instructions and tests.