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

128 Views Asked by At

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?

2

There are 2 best solutions below

2
31piy On BEST ANSWER

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.

0
Sujay Gavhane On

you can create class under lib folder like this

class Subdomain
    def self.matches?(request)
        case request.subdomain
        when SUB_DOMAIN_NAME
          true
        else
          false
        end
    end
end

and in your routes.rb file create routes like this

constraints(Subdomain) do
    get '/about', to: 'marketings#about', as: :about
end

get '/about', to: 'marketings#about', as: :merchant_about