Как включить рабочую точку монтирования ruby ​​on rails в url_helpers для электронной почты?

tl;dnr: ссылки на мои страницы в порядке, но ссылки, преобразованные в нестраничный текст (электронная почта), не имеют точки подключения рабочего приложения.

подробности. Мое приложение RoR использует немного разные URL-адреса в разработке и производстве: в разработке объектом верхнего уровня является модель ресурсов:

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

Но в рабочей среде приложение монтируется на один уровень ниже, поэтому URL-адреса имеют дополнительный термин:

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

В большинстве случаев это работает нормально: url_helpers, такие как edit_entity_url, возвращают URL-адреса, как я их показал. Честно говоря, я не совсем понимаю, как это работает; Я полагаю, что Phusion Passenger и Rack справятся?

Однако, когда я отправляю электронное письмо (например, для подтверждения сброса пароля), оно не работает: edit_entity_url никогда не добавляет точку монтирования APP. За исключением моей собственной условной логики в ERB, как я могу получить там этот «/APP»?

Что я пробовал:

  • Настройка Rails.application.routes.default_url_options[:host] для включения «/registry» (без эффекта)
  • используя <%= link_to 'Reset', edit_entity_url(...) %> (без помощи)

Информация о версии:

  • почтовая программа (4.0.2)
  • Рельсы 4.0.2
  • рубин 2.1.0p0
  • стойка (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" <[email protected]>},
  :exception_recipients => %w{[email protected]}
}

Просмотр сообщения электронной почты (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.  

Да, странно основывать URL-адрес на reset_token, а не на user_id, но он обрабатывается в контроллере. Структура основана на Railscast #274.


person jackr    schedule 23.01.2014    source источник
comment
Теперь, когда я опубликовал, похожие вопросы StackOverflow, гремлин указывает на этот очень похожий вопрос без ответа 9-месячной давности: RackEnv не соблюдается при использовании помощников маршрута из модели   -  person jackr    schedule 23.01.2014
comment
В различных дискуссиях с возможностью поиска предлагается создать виртуальный хост, а не изменять URL-адрес, но это связано с записями DNS, которые выходят за рамки моей непосредственной компетенции.   -  person jackr    schedule 24.01.2014


Ответы (2)


Что ж, это отвратительный хак, но я "решил" это вручную. В 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) %>

Все еще интересно, если у кого-то есть идея получше!

person jackr    schedule 23.01.2014

Вы можете передать параметр :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 = '/your-mount-point' в config.

Подробнее об этом здесь: как -to-get-ruby-on-rails-production-mount-point-included-in-url-helpers-for-email

person jpgeek    schedule 02.06.2014