ActionController :: Base.relative_url_root的替代品是什么?
我正在将2.x rails应用程序移植到rails3; 我们称之为foo-app。 Foo-app是更大的rails应用程序的一部分,位于main_rails_app.com/foo-app。 以前我们只是在foo-app生产配置中设置以下内容,以确保我们的foo-app路由正常工作:
ActionController::Base.relative_url_root = "/foo-app"
但是,使用rails3,我现在得到:
DEPRECATION WARNING: ActionController::Base.relative_url_root is ineffective. Please stop using it.
我已经将配置条目更改为以下内容:
config.action_controller.relative_url_root = "/foo-app"
这主要是因为所有对外部资源(javascript / css / images)的调用都将使用/ foo-app。 但是,我的路线没有任何改变,换句话说,foo-app root_path给我’/’当我期待’/ foo-app’。
两个问题:
- 什么是ActionController :: Base.relative_url_root的替代品
- 如果是config.action_controller.relative_url_root,那么为什么我的路由没有反映我设置的relative_url_root值?
您应该能够处理routes.rb文件中的所有内容。 将所有当前路线包裹在范围内; 例如。
scope "/context_root" do resources :controller resources :another_controller match 'welcome/', :to => "welcome#index" root :to => "welcome#index" end
然后,您可以通过rake routes
validation您的路由,他们应该相应地显示您的路由,包括您的上下文根(relative_url_root)
如果您通过Passenger进行部署,请使用RackBaseURI
指令: http : //www.modrails.com/documentation/Users%20guide%20Apache.html#RackBaseURI
否则,您可以使用以下块将config.ru
语句包装在config.ru
:
map ActionController::Base.config.relative_url_root || "/" do run FooApp::Application end
然后,您只需将环境变量RAILS_RELATIVE_URL_ROOT
设置为“/ foo-app”。 这甚至适用于在gem或插件中设置的路线。
警告:不要混用这两种解决方案。
我觉得我必须过度复杂化和/或遗漏一些东西,但这个问题让我感到沮丧一段时间了,这是我的笔记。
摘要
有两个单独的问题,每个问题有两个点用于动态和静态路由:
- 如何使路由正确匹配传入的URL
- 用于路线
- 对于静态文件
- 如何生成包含relative_root的URL
- 通过url助手
- 对于静态资产
解决所有四点的一种方法:
- 配置Nginx以剥离
relative_root
部分- 这解决了路线匹配问题; 只需编写期望URL处于
/
喜欢开发的路由 - 静态文件也在开发中提供
- 这解决了路线匹配问题; 只需编写期望URL处于
- 设置
RAILS_RELATIVE_URL_ROOT
环境变量- 这解决了生成的静态资产助手
- 使用下面的
ScriptName
中间件(修改它以使用环境中的值)- 这解决了生成的url助手,例如
users_path
- 这解决了生成的url助手,例如
在config.ru中将Rails应用程序包装在Rack :: URLMap中(Christoph的回答)
# config.ru map '/relative_root' do run Myapp::Application end
- 要求传入的URL包含relative_url_root(Nginx可以配置为删除或保留此;请参阅下文)
- Rack将relative_url_root附加到Rack env
SCRIPT_NAME
rack / urlmap.rb:62 - Rails将当前请求的
SCRIPT_NAME
到url_for options metal / url_for.rb:41 - Rails’url_for在生成路径routing / url_for.rb:133时预先设置脚本名称
因此,它涵盖了由url帮助程序生成的URL,例如,给定UserController
, users_path
将以相对url根为前缀。
在中间件中设置SCRIPT_NAME
# config.ru class ScriptName def initialize(app, name) @app = app @name = name end def call(env) env['SCRIPT_NAME'] += @name @app.call(env) end end use ScriptName, '/relative_root' run Rails.application
- 与上面的效果相同,但是
- 要求传入的URL不包含relative_url_root
设置RAILS_RELATIVE_URL_ROOT
- 值保存在
app.config.relative_url_root
configuration.rb中:41 - 这又会影响资产路径asset_url_helper.rb:137
- 但就我而言,就是这样
- 特别是不影响url助手
设置config.action_controller.relative_url_root
- ?? 可能影响资产编制?
- 覆盖RAILS_RELATIVE_URL_ROOT env var?
明确定义/relative_root
下的所有路由(rizzah的答案)
# config/routes.rb Myapp::Application.routes.draw do scope '/relative_root' do ... end end
- Url助手将生成正确的URL
- 传入的URL必须包含相对URL根(对Nginx配置敏感,见下文),否则“无路由匹配”例外
- 请求静态资产的URL,例如
/relative_root/images/logo.png
将导致“无路由匹配”exception。 如果nginx无论如何都在提供静态资产,这可能不是问题。
Nginx配置
给出这样的配置:
upstream myapp { server localhost:3000; } server { ... location /relative_root { proxy_pass http://myapp/; } }
Nginx将删除/relative_root
,Rails应用程序将无法看到它。 如果您需要Rails应用程序,请查看它,一种方法是更改proxy_pass
行:
... proxy_pass http://myapp/relative_root/; ...
- AWS S3 Ruby url_for响应标头(自定义文件名和文件类型)
- 如何从Rails中的Warden / Devise after_authentication回调访问会话
- 允许用户在rails 3中删除自己的注释
- 渲染json的数组问题
- 设计/ Rails – 如何只允许管理员为其他人创建帐户?
- Rails asset pipleline:编译为多个样式表
- rails生成rspec:install config / environments / development.rb:1:在`’:undefined method`configure’
- 在Ruby中重新实现ASP.NET成员资格和用户密码哈希
- 如何建立一对多的关系?