Rails Restful Routing and Subdomains

后端 未结 5 635
悲&欢浪女
悲&欢浪女 2020-12-28 17:57

I wondered if there were any plugins or methods which allow me to convert resource routes which allow me to place the controller name as a subdomain.

Examples:

相关标签:
5条回答
  • 2020-12-28 18:45

    I think that subdomain-fu plugin is exacly what you need. With it you will be able to generate routes like

    map.resources :universities,
        :controller => 'education_universities',
        :only => [:index, :show],
        :collection => {
            :all    => :get,
            :search => :post
        },
        :conditions => {:subdomain => 'education'}
    

    This will generate the following:

    education.<your_site>.<your_domain>/universities GET
    education.<your_site>.<your_domain>/universities/:id GET
    education.<your_site>.<your_domain>/universities/all GET
    education.<your_site>.<your_domain>/universities/search POST
    
    0 讨论(0)
  • 2020-12-28 18:46

    Ryan Bates covers this in his Railscast, Subdomains.

    0 讨论(0)
  • 2020-12-28 18:47

    As ileitch mentioned you can do this without extra gems it's really simple actually.

    I have a standard fresh rails app with a fresh user scaffold and a dashboard controller for my admin so I just go:

    constraints :subdomain => 'admin' do
        scope :subdomain => 'admin' do
            resources :users
    
            root :to => "dashboard#index" 
        end
    end
    

    So this goes from this:

    • site.com/users

    to this :

    • admin.site.com/users

    you can include another root :to => "{controller}#{action}" outside of that constraint and scope for site.com which could be say a pages controller. That would get you this:

    constraints :subdomain => 'admin' do
        scope :subdomain => 'admin' do
            resources :users
    
            root :to => "dashboard#index" 
        end
    end
    
    root :to => "pages#index"
    

    This will then resolve:

    • site.com
    • admin.site.com
    • admin.site.com/users
    0 讨论(0)
  • 2020-12-28 18:51

    The best way to do it is to write a simple rack middleware library that rewrites the request headers so that your rails app gets the url you expect but from the user's point of view the url doesn't change. This way you don't have to make any changes to your rails app (or the routes file)

    For example the rack lib would rewrite: users.example.com => example.com/users

    This gem should do exactly that for you: http://github.com/jtrupiano/rack-rewrite

    UPDATED WITH CODE EXAMPLE

    Note: this is quickly written, totally untested, but should set you on the right path. Also, I haven't checked out the rack-rewrite gem, which might make this even simpler

    # your rack middleware lib.  stick this in you lib dir
    class RewriteSubdomainToPath
    
      def initialize(app)
        @app = app
      end
    
      def call(env)
        original_host = env['SERVER_NAME']
        subdomain = get_subdomain(original_host)
        if subdomain
          new_host = get_domain(original_host)
          env['PATH_INFO'] = [subdomain, env['PATH_INFO']].join('/')
          env['HTTP_X_FORWARDED_HOST'] = [original_host, new_host].join(', ')
          logger.info("Reroute: mapped #{original_host} => #{new_host}") if defined?(Rails.logger)
        end
    
        @app.call(env)
    
      end
    
      def get_subdomain
        # code to find a subdomain.  simple regex is probably find, but you might need to handle 
        # different TLD lengths for example .co.uk
        # google this, there are lots of examples
    
      end
    
      def get_domain
        # get the domain without the subdomain. same comments as above
      end
    end
    
    # then in an initializer
    Rails.application.config.middleware.use RewriteSubdomainToPath
    
    0 讨论(0)
  • 2020-12-28 18:51

    This is possible without using plugins.

    Given the directory structure app/controllers/portal/customers_controller.rb And I want to be able to call URL helpers prefixed with portal, i.e new_portal_customer_url. And the URL will only be accessible via http://portal.domain.com/customers. Then... use this:

    constraints :subdomain => 'portal' do
      scope :module => 'portal', :as => 'portal', :subdomain => 'portal' do
        resources :customers
      end
    end
    
    0 讨论(0)
提交回复
热议问题