11

有什么方法可以让 url_for 在动作调度路由期间根据 request.host 返回 url?

mount Collaborate::Engine => '/apps/collaborate', :constraints => {:host => 'example.com' }
mount Collaborate::Engine => '/apps/worktogether'

例子:

当用户在 example.com 主机上时

协作路径 => /apps/collaborate

当用户在任何其他主机上时

协作路径 => /apps/worktogether

经过大量研究,我意识到 RouteSet 类具有 named_routes ,它不考虑返回 url 的约束。

我已经尝试在 action_dispatch/routing/route_set.rb 中覆盖 @set 以从 rails 应用程序拾取,但 dint 按预期工作

@search_set = Rails.application.routes.set.routes.select{|x| x.defaults[:host] == options[:host] }[0]
@set = @search_set unless @search_set.blank?
4

3 回答 3

7

在您的示例中删除 .com

mount Collaborate::Engine => '/apps/collaborate', :constraints => {:host => 'examplesite' }
mount Collaborate::Engine => '/apps/worktogether'

应该只是工作

如果您需要更高级的约束,请创建自己的约束:

class CustomConstraint
  def initialize
    # Things you need for initialization
  end

  def matches?(request)
    # Do your thing here with the request object
    # http://guides.rubyonrails.org/action_controller_overview.html#the-request-object
    request.host == "example"
  end
end

Rails.application.routes.draw do
  get 'foo', to: 'bar#baz',
    constraints: CustomConstraint.new
end

您还可以将约束指定为 lambda:

Rails.application.routes.draw do
  get 'foo', to: 'foo#bar',
    constraints: lambda { |request| request.remote_ip == '127.0.0.1' }
end

来源: http: //guides.rubyonrails.org/routing.html#advanced-constraints

于 2015-12-17T13:15:48.953 回答
2

至于我担心如果你在中间件级别处理它会很好。这是我的假设。

将此行添加到config/application.rb

config.middleware.insert_before ActionDispatch::ParamsParser, "SelectiveStack"

在 app 目录中添加中间件,中间件目录为约定

app/middleware/selective_stack.rb

class SelectiveStack
  def initialize(app)
    @app = app
  end

  def call(env)
    debugger
    if env["SERVER_NAME"] == "example.com"
      "/apps/collaborate"
    else
      "/apps/worktogether"
    end
  end


end

希望这能解决你的问题。!!!

于 2015-12-17T12:29:41.137 回答
1

Alright, here's a shot in the dark; maybe you've tried it already or maybe I'm really missing something. On the surface, it really looks like you're just trying to override a path helper method for apps. So why not set up an override in the application_helper.rb? Something like:

module ApplicationHelper
  def collaborate_path
    if request.domain == "example.com"
      "/apps/collaborate"
    else
      "/apps/worktogether"
    end
  end
end
于 2015-12-14T20:55:03.467 回答