How to Add Dynamic Subdomain in Rails Application

Search for a command to run...

No comments yet. Be the first to comment.
I recently purchased Makerkit, a SaaS boilerplate built with Next.js, Remix, Firebase and Supabase to build SaaS products in record time. The issue with this template when I use in a project is the author was extremely active updating the template's ...

Me: "Tadaima"; My Personal Laptop: "Okaerinasai"

What are the reasons for using Rust as a language for developing web applications? Can't we rely on established languages that are already suitable for web development? Here are some justifications for choosing Rust as the programming language for cr...

Getting started to be a Rust developer

A tutorial to get to know Elasticsearch and how to use it in your next project

For those who want to implement subdomain programmatically within your rails application, you can follow these few steps:
First, let’s create an Account model as a table to store subdomain names that we will accept in our application.
rails g model Account subdomain:string
From the above generator, it generates a migration file. We can then do rails db:migrate.
Create a new file inside the /lib folder and give it the name, say subdomain.rb.
Add this code inside that file:
class Subdomain
def self.matches?(request)
request.subdomain.present? && request.subdomain != "www"
end
end
Then we need to modify a bit our routes.rb by adding constraints to every URLs that we will use under the subdomain. For an example, pages_controller.rb needs to be accessible under a specific subdomain, so we can write our route like this:
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
constraints(Subdomain) do
get '/', to: 'pages#index'
end
end
We will then need to add before_action :require_subdomain since the controllers need to be strictly accessible from the subdomain only. This is achievable by modifying our application_controller.rb:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
helper_method :require_subdomain
private
def require_subdomain
not_found unless subdomain_exist?
end
def subdomain_exist?
account = Account.find_by_subdomain(request.subdomain)
!!account
end
def not_found
raise ActionController::RoutingError.new('404')
end
end
In the application_controller.rb above we now have a helper method called require_subdomain, which is reusable to each controller that requires to be authorized by the subdomain.
class PagesController < ApplicationController
before_action :require_subdomain
def index
# controller logic goes here
end
end
Let's use rails console to create a dummy for our Account or subdomain.
$ rails c
Running via Spring preloader in process 15151
Loading development environment (Rails 6.0.0)
2.6.5 :001 > Account.new(subdomain: 'test').save
(0.4ms) SET NAMES utf8, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
(0.3ms) BEGIN
Account Exists (0.7ms) SELECT 1 AS one FROM `accounts` WHERE `accounts`.`subdomain` = BINARY 'test' LIMIT 1
SQL (0.5ms) INSERT INTO `accounts` (`subdomain`, `created_at`, `updated_at`) VALUES ('test', '2017-07-22 14:58:35', '2017-07-22 14:58:35')
(35.5ms) COMMIT
=> true
Open the browser then visit http://test.lvh.me:3000 and also try accessing some random subdomain, for example, http://doesnotexist.lvh.me:3000.
About lvh.me domain, you can check this article out
If the subdomain is registered in Account

Subdomain doesn't exist in Account

Tip:
We can add some extra validation layers in the Account creation so we can preserve some subdomain names so your user cannot claim those (i.e. www, admin, app, etc).
Thank you!