zoukankan      html  css  js  c++  java
  • rails3已经内置subdomain

    1. Custom Subdomains in Rails 3

      Rails 3 supports subdomains out of the box, which is great. But did you know that the constraints in the Router can actually match patterns too? This means instead of hardcoding each subdomain into your routes you can allow your customers to decide their own subdomains.

      However, we have to be careful with pattern matching on the subdomain. There are obvious subdomains we don’t want to match. Like ‘www’, ”, nil, and others that we may reserve. In this case using a pattern match might not be best.

      Thankfully the Rails 3 Router constraints can also take objects. As long as the object responds to Object.matches?. The request is passed to the method and you can act on it in any way. The following is the solution that I’ve found works for me.

      I created a ‘lib/sub_domain.rb’ with the following code:

      # lib/sub_domain.rb
      class SubDomain
        def self.matches?(request)
          case request.subdomain
          when 'www', '', nil
            false
          else
            true
          end
        end
      end
      

      In my routes.rb file I can now wrap all routes I want under a custom subdomain

      # config/routes.rb
      TestApp::Application.routes.draw do |map|
        constraints(SubDomain) do
          root :to => "customers#index"
        end
        
        root :to => "home#index"
      end
      

      Finally, I create a SubDomainController from which all controllers under the subdomain constraint can inherit from

      # app/controllers/sub_domain_controller.rb
      class SubDomainController < ApplicationController
        before_filter :get_customer_from_subdomain
        
        private
        
        def get_customer_from_subdomain
          @customer = Customer.find_by_subdomain!(request.subdomain)
        end
      end
      
      # app/controllers/customers_controller.rb
      class CustomersController < SubDomainController
        def index
          ...
        end
      end
      

      Having the SubDomainController is a nice way for me to encapsulate behavior that I want every subdomain to have. One such idea would be customer specific layouts. (or themes)

      Check out Phil McClure’s post on localhost subdomains if you want to use this functionality in your development and test environments.

      Update

      To link to your dynamic subdomains you can completely overwrite the :host option in the url helper:

      root_url(nil, {:host => "subdomain.somedomain.com"})
      

      This is not ideal. It constrains us to this particular domain. What we need is to be able to pass a :subdomain option to the url helper. (btw, you need to use the url helpers for linking to subdomains and not the path helpers)

      So I quickly wrote up this code. Just add it to your ApplicationController and it will be available to your entire app:

      class ApplicationController < ActionController::Base
        ...
        private
        
        # To write subdomains on the url helpers:
        # root_url(nil, {:subdomain => "subdomain"})
        def url_for(options = nil)
          case options
          when Hash
            if subdomain = options.delete(:subdomain)
              if request.subdomain.empty?
                options[:host] = "#{subdomain}.#{request.host_with_port}"
              else
                options[:host] = request.host_with_port.sub(request.subdomain, subdomain)
              end
            end
          end
          super
        end
      end
      

      So now you can do:

      root_url(nil, {:subdomain => "subdomain"})
      

    Notes

    1. jackhq reblogged this from bcardarella
    2. bcardarella posted this
    • 4 people liked this.
    Community

    Add New Comment

    Showing 1 comments

    Sort by   Subscribe by email   Subscribe by RSS
    • A tip for people trying to use the url_for method...

      Adding that method to the ApplicationController will only allow subdomains to be used in your controllers. If you want to do the same in your views then you'll need to add:

      helper_method :url_for

      to your ApplicationController as well.
  • 相关阅读:
    【51nod 1331】狭窄的通道
    【noip 2016】提高组
    【noip 2016】普及组
    【bzoj 4764】弹飞大爷
    线筛
    高斯消元
    网络流
    平衡二叉树 treap

    双向广搜
  • 原文地址:https://www.cnblogs.com/lexus/p/1907726.html
Copyright © 2011-2022 走看看