如何在电子邮件的url_helpers中包含ruby on rails production mount-point?

时间:2014-01-23 19:35:47

标签: ruby-on-rails passenger rack

tl; dnr :我的页面链接很好,但是链接到非页面文本(电子邮件)的链接缺少生产应用程序挂载点。

详细信息:我的RoR应用在开发和生产中使用略有不同的网址:在开发中,顶级实体是资源模型:

http://localhost:3000/ENTITY/1/edit

但是在制作中,应用程序安装了一级,因此URLS有一个额外的术语:

https://server.example.com/APP/ENTITY/1/edit

这适用于大多数情况:url_helpers(如edit_entity_url)会返回我显示的网址。坦率地说,我不清楚究竟是如何运作的;我想Phusion Passenger和Rack可以解决这个问题吗?

但是,当我发送电子邮件(例如确认密码重置)时,它不起作用:edit_entity_url从不添加APP挂载点。在ERB中缺少我自己的条件逻辑,我怎么能在那里得到那个“/ APP”?

我尝试过的事情:

  • 设置`Rails.application.routes.default_url_options [:host]以包含“/ registry”(无效)
  • 使用<%= link_to 'Reset', edit_entity_url(...) %>(没有帮助)

版本信息:

  • actionmailer(4.0.2)
  • Rails 4.0.2
  • ruby​​ 2.1.0p0
  • rack(1.5.2)
  • 乘客(4.0.35)

Apache“启用站点”的文件将事物联系在一起(我唯一能找到“/ registry”令牌的地方):

<VirtualHost *:80>
    ServerName server.example.com
        DocumentRoot /var/www
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>

    Alias /registry /app01/capapp/registry/current/public
    <Location /registry>
        PassengerBaseURI /registry
        PassengerAppRoot /app01/capapp/registry/current
    </Location>
    <Directory /app01/capapp/registry/current/public>
        Allow from all
        Options -MultiViews
    </Directory>

    ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
    <Directory "/usr/lib/cgi-bin">
        AllowOverride None
        Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
        Order allow,deny
        Allow from all
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log

    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined

    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>

</VirtualHost>

Rails config/environments/production.rb文件。

Registration::Application.configure do
  config.cache_classes = true
  config.eager_load = true
  config.consider_all_requests_local       = false
  config.action_controller.perform_caching = true
  config.serve_static_assets = false
  config.assets.js_compressor = :uglifier
  config.assets.compile = false
  config.assets.digest = true
  config.assets.version = '1.0'
  config.log_level = :debug
  config.i18n.fallbacks = true
  config.active_support.deprecation = :notify
  config.log_formatter = ::Logger::Formatter.new
  Rails.application.routes.default_url_options[:host] = "server.example.com"
end

Registration::Application.config.middleware.use ExceptionNotification::Rack,
:email => {
  :email_prefix => "[Registration]",
  :sender_address => %{"Admin" <XXX@example.com>},
  :exception_recipients => %w{XXX@example.com}
}

查看电子邮件(app/views/user_mailer/password_reset.text.erb):

To reset your password click the URL below.  

<%= edit_password_reset_url(@user.password_reset_token) %>

If you did not request your password to be reset please ignore this email 
and your password will stay as it is.  

是的,基于reset_token而不是user_id的URL是很奇怪的,但它是在控制器中处理的。基于Railscast #274

的结构

2 个答案:

答案 0 :(得分:0)

嗯,这是一个恶心的黑客,但我通过人工干预“解决了”这个问题。在app/views/user_mailer/password_reset.text.erb中,我现在说:

To reset your password click the URL below.  

<%  url = root_url.chomp('/') %>
<%  url += "/registry" if Rails.env.production? %>
<%= url + edit_password_reset_path(@user.password_reset_token) %>

如果有人有更好的主意,仍然感兴趣!

答案 1 :(得分:0)

您可以将:script_name参数传递给url_for(或其他基于url_for的方法)来设置挂载点。我用

url_for( :only_path => false,
:host => some.host,
:script_name => Rails.application.config.relative_url_root
...

并设置config.relative_url_root =&#39; / your-mount-point&#39;在配置中。

有关它的更多详情: how-to-get-ruby-on-rails-production-mount-point-included-in-url-helpers-for-email