ruby-on-railsroutesrails-routingurl-helper

Inspect a given route to determine if it has a subdomain constraint


I'm building a Rails app that has a merchant subdomain. I have these two routes:

get '/about', controller: :marketing, action: :about, as: :about
get '/about', controller: :merchant, action: :about, constraints: { subdomain: 'merchant' }, as: :merchant_about

But when I use their URL helpers both merchant_about_url and about_url result in http://example.com/about.

I know I can specify the subdomain argument on the helper to prefix the URL with the subdomain, but since these URLs are going to be frequently used in various cases I'd like to build a wrapper for this helper to make it smarter.

My question: Can I inspect a given route to see if it has a subdomain constraint?

If I can, I'd like to do something like the following:

def smart_url(route_name, opts={})
  if # route_name has subdomain constraint
    opts.merge!({ subdomain: 'merchant' })
  end

  send("#{route_name}_url", opts)
end

In doing this, I can effectively call:

smart_url('about')          # http://example.com/about
smart_url('merchant_about') # http://merchant.example.com/about

Is this possible?


Solution

  • Can I inspect a given route to see if it has a subdomain constraint?

    Yes, that is possible. You need to use Rails' routes API to get info about the route.

    def smart_url(route_name, opts={})
      route = Rails.application.routes.routes.detect {|r| r.name == route_name }
    
      if opts.is_a? Hash && route&.constraints[:subdomain]
        opts.merge!({ subdomain: 'merchant' })
      end
    
      send("#{route_name}_url", opts)
    end
    

    The above searches a route by its name, and inspects its constraints if the route is found.