2

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

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

http://localhost:3000/verify/a1b2c3

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

http://my.url/qa

这是通过/qa在适当的.htaccess文件中设置 RailsBaseURI 来完成的。因此,我正在尝试在我的 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某种方式设置它,这样当从一个环境移动到另一个环境时,我根本不需要更改我的应用程序。

提前致谢!

4

2 回答 2

2

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

更新

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

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

为了减少投入生产后必须进行的更改量,我建议您在初始化程序中定义一个常量(in /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那些绕过这个问题的助手。

于 2011-05-10T07:05:59.337 回答
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' }

这样,代码不必在环境之间更改一点,因此,我真的不在乎我在哪个域、子域或端口上运行......它只是工作。希望这对将来的其他人有所帮助。谢谢!

于 2011-05-12T02:50:36.947 回答