为生成的链接添加前缀,但不为传入路由添加前缀
Add a prefix to generated links, but not to incoming routes
我们的 Rails 4 应用程序需要通过一个古老的门户网站进行访问。该门户通过向每个 URL 添加(从浏览器的角度)前缀来工作;在将请求转发到我的应用程序之前,此前缀已被门户删除。
所以浏览器调用https://portal.company.com/portal/prefix/xyzzy/myapp/mymodel/new
;门户网站做它的事情并请求 https://myserver.company.com/myapp/mymodel/new
(以某种不相关的方式传递剥离的前缀)。前缀是动态的,可以在请求之间更改。
问题是门户无法重写我的应用程序提供的 HTML 页面。也就是说,它不放在前缀中。它期望应用程序要么只发出相对 URLs,要么自己添加门户前缀。
所以:
- 例如,当直接访问应用程序时,常规 URL
/myapp/mymodel/new
必须保持原样(对于不使用门户的某些用户)。
- 当通过门户访问时,我们的应用程序必须像往常一样理解
/myapp/mymodel/new
,但是当使用 mymodel_new_path
或 link_to @mymodel
或 form_for @my_model
或任何其他魔法时 URL 生成器有,它必须添加门户前缀。因此,应用程序发出的任何 URL 必须看起来像 /portal/prefix/xyzzy/myapp/mymodel/new
,其中每个请求字符串 /portal/prefix/xyzzy
由我们定义的某些方法给出(并且 xyzzy
部分可以更改在请求之间)。
我怎样才能做到这一点?我的 routes.rb
今天看起来像这样:
MyApp::application.routes.draw do
scope ' /myapp' do
get ...
这可能必须保持原样,因为来自门户的传入请求中的 URLs 不会更改。但是我如何影响即将离任的 URLs?
此建议将允许您根据需要轻松地为 Rails 路径助手生成的 url 添加前缀。但是请注意,它还会使这些扩展路径对您的应用程序有效请求 - 它们应该只路由到预期的位置,但您会在 params
哈希中获得一些您可以忽略的额外值,所以我怀疑这一点可能是可以接受的。
首先,将所有前缀位作为可选参数添加到路由的基本范围:
scope '(:portal/)(:prefixA/)(:prefixB)/myapp' do
# routes
end
请注意,那些可选参数不能包含 /
字符,除非它被路径助手转义,所以如果你在前缀中有几个级别(看起来你在问题中这样做)你将需要几个不同的参数,除了最后一个参数外,所有参数都跟在斜线后面,如上所示。
完成后,您应该在 ApplicationController
中定义 default_url_options
,它应该 return 您在路由中需要的值的散列:
def default_url_options(_options={})
{
portal: 'portal',
prefixA: 'whatevertheprefixis',
prefixB: 'nextbitoftheprefix'
}
end
应该做到这一点,路径助手(以及 link_to @object
等)现在应该在您每次使用它们时都包含这些值。
请注意,由于开始的 portal
位也是一个可选参数,您可以简单地向 default_url_options
添加额外的逻辑,并在任何时候将其 return 设为空散列不想要这种前缀行为。
我们的 Rails 4 应用程序需要通过一个古老的门户网站进行访问。该门户通过向每个 URL 添加(从浏览器的角度)前缀来工作;在将请求转发到我的应用程序之前,此前缀已被门户删除。
所以浏览器调用https://portal.company.com/portal/prefix/xyzzy/myapp/mymodel/new
;门户网站做它的事情并请求 https://myserver.company.com/myapp/mymodel/new
(以某种不相关的方式传递剥离的前缀)。前缀是动态的,可以在请求之间更改。
问题是门户无法重写我的应用程序提供的 HTML 页面。也就是说,它不放在前缀中。它期望应用程序要么只发出相对 URLs,要么自己添加门户前缀。
所以:
- 例如,当直接访问应用程序时,常规 URL
/myapp/mymodel/new
必须保持原样(对于不使用门户的某些用户)。 - 当通过门户访问时,我们的应用程序必须像往常一样理解
/myapp/mymodel/new
,但是当使用mymodel_new_path
或link_to @mymodel
或form_for @my_model
或任何其他魔法时 URL 生成器有,它必须添加门户前缀。因此,应用程序发出的任何 URL 必须看起来像/portal/prefix/xyzzy/myapp/mymodel/new
,其中每个请求字符串/portal/prefix/xyzzy
由我们定义的某些方法给出(并且xyzzy
部分可以更改在请求之间)。
我怎样才能做到这一点?我的 routes.rb
今天看起来像这样:
MyApp::application.routes.draw do
scope ' /myapp' do
get ...
这可能必须保持原样,因为来自门户的传入请求中的 URLs 不会更改。但是我如何影响即将离任的 URLs?
此建议将允许您根据需要轻松地为 Rails 路径助手生成的 url 添加前缀。但是请注意,它还会使这些扩展路径对您的应用程序有效请求 - 它们应该只路由到预期的位置,但您会在 params
哈希中获得一些您可以忽略的额外值,所以我怀疑这一点可能是可以接受的。
首先,将所有前缀位作为可选参数添加到路由的基本范围:
scope '(:portal/)(:prefixA/)(:prefixB)/myapp' do
# routes
end
请注意,那些可选参数不能包含 /
字符,除非它被路径助手转义,所以如果你在前缀中有几个级别(看起来你在问题中这样做)你将需要几个不同的参数,除了最后一个参数外,所有参数都跟在斜线后面,如上所示。
完成后,您应该在 ApplicationController
中定义 default_url_options
,它应该 return 您在路由中需要的值的散列:
def default_url_options(_options={})
{
portal: 'portal',
prefixA: 'whatevertheprefixis',
prefixB: 'nextbitoftheprefix'
}
end
应该做到这一点,路径助手(以及 link_to @object
等)现在应该在您每次使用它们时都包含这些值。
请注意,由于开始的 portal
位也是一个可选参数,您可以简单地向 default_url_options
添加额外的逻辑,并在任何时候将其 return 设为空散列不想要这种前缀行为。