#85 Working with Subdomains

Summary

Learn to create a multi-tenant application where access to tenants are determined by the subdomain.
rails multitenancy 7:40

Resources

Episode #40 puma-dev - https://www.driftingruby.com/episodes/puma-dev-replacement-for-pow-and-prax
Source - https://github.com/driftingruby/085-working-with-subdomains

Important to note that if you are going to use subdomains and serve traffic over HTTPS, you will need a Wildcard SSL Certificate.

Summary

Terminalpuma-dev link -n example .
pkill -USR1 puma-dev && puma-dev -install && tail -f log/development.log
application_controller.rbclass ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :ensure_subdomain

  def current_blog
    @current_blog ||= Blog.find_by(subdomain: request.subdomain)
  end
  helper_method :current_blog

  private

  def ensure_subdomain
    redirect_to root_url(subdomain: :www) unless current_blog.present?
  end
end
routes.rbRails.application.routes.draw do
  constraints(SubdomainRoutes) do
    resources :blogs, only: [:new]
    root 'welcome#index'
  end
  
  constraints(!SubdomainRoutes) do
    resources :blogs, except: [:index, :new] do
      resources :posts
    end
    root 'blogs#show'
  end
end
config/initializers/subdomain_routes.rbclass SubdomainRoutes
  def self.matches? request
    case request.subdomain
    when '', 'www'
      true
    else
      false
    end
  end
end
blogs_controller.rbclass BlogsController < ApplicationController
  before_action :set_blog, only: [:show, :edit, :update, :destroy]
  skip_before_action :ensure_subdomain, only: [:new, :create]

  def show
  end

  def new
    @blog = Blog.new
  end

  def edit
  end

  def create
    @blog = Blog.new(blog_params)
    if @blog.save
      redirect_to root_path, notice: 'Blog was successfully created.'
    else
      render :new
    end
  end

  def update
    if @blog.update(blog_params)
      redirect_to root_path, notice: 'Blog was successfully updated.'
    else
      render :edit
    end
  end

  def destroy
    @blog.destroy
    redirect_to root_url(subdomain: nil), notice: 'Blog was successfully destroyed.'
  end

  private

    def set_blog
      @blog = current_blog
    end

    def blog_params
      params.require(:blog).permit(:name, :subdomain)
    end
end
welcome_controller.rbclass WelcomeController < ApplicationController
  skip_before_action :ensure_subdomain

  def index
    @blogs = Blog.all
  end
end
models/blog.rbclass Blog < ApplicationRecord
  validates :subdomain, 
            exclusion: { in: %w(www), 
            message: "%{value} is reserved." }, 
            presence: true, 
            uniqueness: true
  before_validation :sanitize_subdomain

  has_many :posts

  private

  def sanitize_subdomain
    self.subdomain = self.subdomain.parameterize
  end
end
blogs/show.html.erb<%= link_to 'Blog Home', root_path, class: 'btn btn-info' %>
<%= link_to 'Site Home', root_url(subdomain: nil), class: 'btn btn-info' %>
welcome/index.html.erb<%= link_to "#{blog.subdomain}.example.dev", root_url(subdomain: blog.subdomain) %>
sadiqmmm said over 1 year ago:

Thanks a lot.

It really helped me. You're an amazing guy.

Jayzen PRO said about 1 month ago:

i now use the puma-dev but i find the app can't load all the js and css file which are included in application.js and application.scss.
i find the current app above in the video use the custom css other than bootstrap, hava you ever come across the problem?

kobaltz PRO said about 1 month ago:

Inspect your browser dev tools to see if there are any errors in loading the assets. It could be CORS policy blocking the assets.

Jayzen PRO said about 1 month ago:

i find the problem, the chrome plugin adblock blocked it

Jayzen PRO said about 1 month ago:

the chrome toos show the errors
ruby
Failed to load resource: net::ERR_BLOCKED_BY_CLIENT

kobaltz PRO said about 1 month ago:

This is usually something with the browser that is blocking the asset. It could be a browser extension or something.

Jayzen PRO said about 1 month ago:

thansk~

Login to Comment