Rails Mailer添加邮件链接遇ActionController::UrlGenerationError求助
解决Rails邮件中
link_to生成URL的ActionController::UrlGenerationError问题 我刚碰到过几乎一模一样的问题,给你梳理下问题根源和落地的解决步骤:
首先,你遇到的ActionController::UrlGenerationError本质是Rails邮件模板没有请求上下文,没法自动解析@message对应的路由。直接把模型实例传给link_to在普通视图里能正常工作,是因为视图自带请求上下文,但邮件模板不行,得明确告诉Rails用哪个路由辅助方法。
具体解决步骤:
先确认你的路由配置
打开config/routes.rb,确保你给Message资源配置了RESTful路由(或者至少有单个消息的专属路由):# 示例:RESTful路由,会自动生成message_path/message_url等路由辅助方法 resources :messages如果是自定义路由,也要确保有对应的辅助方法(比如
view_message_path这类)。修改邮件模板里的
link_to调用
把原来的<%= link_to "See message", @message %>改成明确调用路由辅助方法的形式,并且指定host参数(邮件模板不知道当前服务域名,必须显式声明):<%# 开发环境示例 %> <%= link_to "See message", message_url(@message, host: "localhost:3000") %> <%# 生产环境替换成你的实际域名 %> <%= link_to "See message", message_url(@message, host: "your-app-domain.com") %>配置默认URL(推荐,省得每次写host)
为了不用在每个link_to里重复写host,你可以在环境配置文件里设置全局默认URL:- 开发环境:
config/environments/development.rbconfig.action_mailer.default_url_options = { host: 'localhost:3000' } - 生产环境:
config/environments/production.rbconfig.action_mailer.default_url_options = { host: 'your-production-domain.com' }
配置完成后,模板里的
link_to就能简化成:<%= link_to "See message", message_url(@message) %>- 开发环境:
额外小优化:
看你的邮件代码里两次查询了同一个User,其实可以优化成一次查询,还能避免用户不存在时的报错:
class MessageMailer < ApplicationMailer def new_message(message) @message = message @title = message.title sender = User.find_by_id(message.user_id) # 用&.语法避免sender为nil时抛出NoMethodError @from_first_name = sender&.first_name @from_last_name = sender&.last_name mail to: @message.user.email, subject: "New Message: #{@message.title}" end end
内容的提问来源于stack exchange,提问作者user9680695




