RoR 3,Passenger,相对URL和辅助方法,例如root_url

时间:2011-05-10 02:07:37

标签: ruby-on-rails apache passenger mod-rails

我真的很难理解我在Rails 3应用程序中看到的路由行为,因为它与Passenger和路由助手方法有关。这是一个快速概述:

当用户注册我的网站时,我要做的其中一件事就是发送一封验证邮件,以确保用户提交了有效的电子邮件地址。因此,我设置邮件程序向用户发送带有某种魔术令牌的URL,从而证明他们已收到我发送的电子邮件。电子邮件正文中的URL是通过路由帮助程序方法生成的(在本例中为verify_url("a1b2c3")),并且URL恰好填入电子邮件中:

http://localhost:3000/verify/a1b2c3

这一切在localhost:3000下都很顺利。所以,就像一个负责任的开发人员,我接下来要做的就是将我的应用程序移动到我的远程QA环境并验证一切仍然有效。我的托管服务提供商使用Passenger,我设置它以便可以按如下方式访问我的QA环境:

http://my.url/qa

这是通过在适当的/qa文件中将RailsBaseURI设置为.htaccess来完成的。所以,我正在尝试在我的QA环境中注册该网站,我希望辅助方法verify_url生成以下URL:

http://my.url/qa/verify/a1b2c3

然而,这就是我所得到的:

http://my.url/verify/a1b2c3

请注意明显缺乏对“qa”路径的引用?我搜索了各种博客和手册寻找答案,我看到了以下建议:

  • 设置环境变量,例如ENV['RAILS_RELATIVE_URL_ROOT']
  • ActionController::Base.relative_url_root
  • 中设置environment/qa.rb
  • 将地图添加到我的config.ru以在特定路径下初始化我的应用
  • 将我的路线包裹在范围内

但是,这些似乎要么被弃用(前两个选项),要么最终产生冗余路径信息(后两个选项),如下所示:

http://my.url/qa/qa/verify/a1b2c3

任何人都可以告诉我设置它的正确方法,这样当我调用verify_url("a1b2c3")时,我实际上得到了正确的URL,包括我的QA环境的相对路径?理想情况下,我希望能够以某种方式在environments/qa.rb中进行设置,这样当从一个环境移动到下一个环境时,我根本不需要更改我的应用程序。

提前致谢!

2 个答案:

答案 0 :(得分:2)

我会忽略整个/qa/并将暂存移至类似http://qa.my.url/的子域,否则您将不得不对可能以负面方式影响生产的代码进行更改。

<强>更新

我忽略了你想在电子邮件中使用这些路线的事实。在这种情况下,您必须在网址助手中设置:host

verify_url(:id=>"a1b2c3", :host=>"qa.my.url")

为了减少投入生产后必须进行的更改量,我建议您在初始化程序中定义一个常量(/path/to/app/config/initializers/my_host.rb中):

MY_HOST = 'qa.my.url'

之后,您可以在电子邮件模板中调用verify_url,如下所示:

verify_url(:id=>"a1b2c3", :host=>MY_HOST)

投入生产后,更改MY_HOST常量,您不必担心模板。

在我的观点中,我从不使用*_url助手,只使用*_path助手来解决这个问题。

答案 1 :(得分:0)

在花了一点时间使用ActionMailer文档之后,事实证明有一个更简单的解决方案,至少对于我想要实现的目标而言。 Wukerplank肯定回答了我的问题,但似乎我并没有提出正确的问题。 : - )

我真正需要查看完全限定的URL的唯一时间是我在邮件中工作,对吧?否则,路径工作正常。好吧,事实证明,ActionMailer允许您在每个环境的基础上指定默认的URL选项。在我的environments/development.rb配置文件中,我现在有以下内容:

config.action_mailer.default_url_options = { :host => 'localhost:3000' }

当我转到我的QA环境时,我只需告诉Passenger我正在使用QA运行,并且有类似environments/qa.rb配置的内容:

config.action_mailer.default_url_options = { :host => 'qa.my.url' }

这样,代码不必在环境之间改变一点,因此,我真的不关心我正在运行的域,子域或端口......它只是起作用。希望这有助于将来的其他人。谢谢!