How to get the subdomain value from a url?
Asked Answered
P

11

31

how can I get the subdomain value in rails, is there a built-in way to do this?

e.g.

test123.example.com

I want the test123 part of the url.

Pyretic answered 30/11, 2010 at 4:31 Comment(2)
you mind using a regular expression?Del
I think this would be better answered by providing a solution to find the subdomain of a string as well as the current url. Considering this is the #1 result on google for the search "rails get the subdomain of a url"Man
T
32

Rails 3.0 has this capability built-in, you can access the subdomain from request.subdomain.

You can also route based on the subdomain:

class SupportSubdomain
  def self.matches?(request)
    request.subdomain == "support"
  end
end

Basecamp::Application.routes do
  constraints(SupportSubdomain) do
    match "/foo/bar", :to => "foo#bar"
  end
end

If you're using 2.3, you'll need to use a plugin such as subdomain-fu.

Tusk answered 30/11, 2010 at 4:40 Comment(3)
Is there a way to do this when using Rack Middleware? request.subdomain is not available only request.hostBurger
@Burger You could try something like this, or rack-subdomain for more complex situations.Tusk
@CyleHunter sure, if you're using something like pow to do development name-resolution.Tusk
C
13

Use the following method inside your controller

request.subdomains

This Returns an array of subdomains

Clamatorial answered 28/3, 2016 at 20:9 Comment(1)
request.subdomain does not return an array. request.subdomains does. Note the plural form of subdomain.Kenward
M
8

In case you are working with a string, and assuming it can be a true URI, you can do this to extract the subdomain.

require 'uri'

uri = URI.parse('http://test123.example.com')
uri.host.split('.').first
=> "test123"

https://mcmap.net/q/470872/-how-to-parse-a-url-and-extract-the-required-substring

Man answered 14/1, 2016 at 4:8 Comment(4)
Gave a -1 since Rails has a built in function that does this already, so this would reinvent the wheel and might be more prone to errors.Shameful
+1 because I actually needed to parse a string. I was trying to parse request.referrer. Don't listen to @corvuszero. The question wasn't specific. Thanks!Upstanding
I gave a +1 since you don't always have a request to work withPhallic
this will fail for TLDs that contain a period, such as mysite.co.uk for example.Piglet
C
7

account_location is also a good plugin. After using it, you can find the account based on different subdomains. And you can find out subdomain from url just by writing

request.subdomains(0).first
in your code.
Centillion answered 30/11, 2010 at 6:58 Comment(0)
A
2

Simple in your controller just do the following

unless request.subdomains.any?
   #No domains available redirect
   redirect_to subdomain: 'www'
end
Austro answered 19/10, 2014 at 2:24 Comment(0)
R
1

You can use the SubdomainFu plugin. This plugin gives you a method current_subdomain which returns the current_subdomain of your app.

You can also have a look at this Railscast

UPDATE

You can also use request.subdomains this will give you an array of subdomains.

Radiophotograph answered 30/11, 2010 at 9:31 Comment(0)
C
1

For anyone looking to get the subdomains on localhost using WEBrick:

Put config.action_dispatch.tld_length = 0 into config/environments/development.rb and everything should work.

Link to SO post here: Can I make Rails / WEBrick recognize entries in /etc/hosts as subdomains (instead of domains)?

Link to Github post: https://github.com/rails/rails/issues/12438

Cotoneaster answered 25/6, 2015 at 22:50 Comment(1)
That is indeed a nice little gotcha there! Glad you mentioned thisFacing
S
1

current domain with subdomains:

"#{request.subdomain}.#{request.domain}"
# or
"#{request.subdomains.join(".")}.#{request.domain}"
Spiky answered 7/8, 2020 at 9:53 Comment(1)
Conscious this would prepend a . if there's no subdomain; a more robust approach (if subdomain may be blank) is something like current_domain = (request.subdomains + [request.domain]).join('.')Tarantula
A
0

A bit late to the party but here's what I used in older versions of rails.

subdomain = request.subdomains.join('.')

It should be backwards compatible in newer versions

Apteral answered 8/11, 2017 at 20:47 Comment(0)
M
0

Recently worked on similar task - but the goal were to remove the subdomain from URL, ignoring the www and any combination of .co.uk or other top level domain. Maybe someone will find it useful:

def self.remove_subdomain_from_url(url)
  root_domain = 'example'

  uri = URI.parse(url)
  host = uri.host.sub(/^www\./, '')

  root_domain_index = host.split('.').find_index { |host_element| host_element.include?(root_domain) }

  return url if root_domain_index.zero?

  new_host = []
  new_host.push('www') if url.include?('www')
  new_host.concat(host.split('.')[root_domain_index..-1])

  uri.host = new_host.join('.')
  uri.to_s
end

And a bunch of tests that might help you to understand the code:

it 'does not remove www from url' do
  expect(remove_subdomain_from_url('https://www.pl.example.com/path/?originalSubdomain=pl')).to eq(
    "https://www.example.com/path/?originalSubdomain=de"
  )
end

it 'removes subdomain from url' do
  expect(remove_subdomain_from_url('https://www.de.example.com/path/?originalSubdomain=de')).to eq(
    "https://www.example.com/path/?originalSubdomain=de"
  )
end

it 'works properly with http' do
  expect(remove_subdomain_from_url('http://de.example.com/path/?originalSubdomain=de')).to eq(
    "http://example.com/path/?originalSubdomain=de"
  )
end

it 'works properly with nested subdomains' do
  expect(remove_subdomain_from_url('https://nested.subdomain.example.com/')).to eq('https://example.com/')
end

it 'works properly with nested top level domain(suffix)' do
  expect(remove_subdomain_from_url('https://www.de.example.co.uk/path/?originalSubdomain=de')).to eq(
    "https://www.example.co.uk/path/?originalSubdomain=de"
  )
end
Megasporangium answered 21/3, 2023 at 10:44 Comment(0)
B
0

For those seeking a generic but robust solution, Mozilla started a Public Suffix List that is free to use and which is the best solution for generically parsing a hostname into its parts (subdomains, private domain, tlds). This resource was originally intended for browser manufacturers so that they can properly scope cookies and such (else you could create a SameSite cookie for co.uk - and then any server registered under that public suffix could read / write to it).

Unfortunately the Public Suffix List is presently not published in an readily useful format; you will need to use an existing library or write your own parser to transform it into a Suffix Tree or what not so that you can use it to match the top-most domains in a hostname to a public suffix.

The list can be downloaded from: https://publicsuffix.org/list/public_suffix_list.dat

The format of the list is described in detail here: https://github.com/publicsuffix/list/wiki/Format#format

Blown answered 21/4 at 8:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.