Rails Restful Routing和Subdomains

时间:2010-09-07 07:46:32

标签: ruby-on-rails routes subdomain

我想知道是否有任何插件或方法允许我转换资源路由,允许我将控制器名称作为子域。

示例:

map.resources :users
map.resource :account
map.resources :blog
...

example.com/users/mark
example.com/account
example.com/blog/subject
example.com/blog/subject/edit
...

#becomes

users.example.com/mark
account.example.com
blog.example.com/subject
blog.example.com/subject/edit
...

我意识到我可以使用命名路由执行此操作,但想知道是否有某种方法可以保留我当前简洁的routes.rb文件。

5 个答案:

答案 0 :(得分:5)

我认为subdomain-fu插件正是您所需要的。 有了它,您将能够生成像

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

这将生成以下内容:

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

答案 1 :(得分:3)

最好的方法是编写一个简单的机架中间件库来重写请求标头,以便rails应用程序获得您期望的URL,但从用户的角度来看,url不会更改。这样您就不必对rails应用程序(或路径文件)进行任何更改

例如,机架lib将重写:users.example.com =&gt; example.com/users

这个宝石应该完全适合你:http://github.com/jtrupiano/rack-rewrite

更新代码示例

注意:这是快速编写的,完全未经测试,但应该让您走上正确的道路。另外,我还没有检查出机架重写的宝石,这可能会让这更简单

# 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

答案 2 :(得分:3)

这可以不使用插件。

给定目录结构app/controllers/portal/customers_controller.rb 我希望能够调用前缀为portal的URL助手,即new_portal_customer_url。 并且只能通过http://portal.domain.com/customers访问该网址。 然后......用这个:

constraints :subdomain => 'portal' do
  scope :module => 'portal', :as => 'portal', :subdomain => 'portal' do
    resources :customers
  end
end

答案 3 :(得分:2)

正如ileitch所提到的,你可以在没有额外宝石的情况下做到这一点,实际上它非常简单。

我有一个标准的全新rails应用程序,带有一个全新的用户脚手架和一个仪表板控制器供我的管理员使用,所以我就去了:

constraints :subdomain => 'admin' do
    scope :subdomain => 'admin' do
        resources :users

        root :to => "dashboard#index" 
    end
end

所以这就是这个:

  • site.com/users

到此:

  • admin.site.com/users

你可以包含另一个root:to =&gt; “{controller}#{action}”在site.com的约束和范围之外,可以说是一个页面控制器。那会让你这样:

constraints :subdomain => 'admin' do
    scope :subdomain => 'admin' do
        resources :users

        root :to => "dashboard#index" 
    end
end

root :to => "pages#index"

然后解决:

  • site.com
  • admin.site.com
  • admin.site.com/users

答案 4 :(得分:0)

Ryan Bates在他的Railscast Subdomains中介绍了这一点。