You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Rails Mailer添加邮件链接遇ActionController::UrlGenerationError求助

我刚碰到过几乎一模一样的问题,给你梳理下问题根源和落地的解决步骤:

首先,你遇到的ActionController::UrlGenerationError本质是Rails邮件模板没有请求上下文,没法自动解析@message对应的路由。直接把模型实例传给link_to在普通视图里能正常工作,是因为视图自带请求上下文,但邮件模板不行,得明确告诉Rails用哪个路由辅助方法。

具体解决步骤:

  1. 先确认你的路由配置
    打开config/routes.rb,确保你给Message资源配置了RESTful路由(或者至少有单个消息的专属路由):

    # 示例:RESTful路由,会自动生成message_path/message_url等路由辅助方法
    resources :messages
    

    如果是自定义路由,也要确保有对应的辅助方法(比如view_message_path这类)。

  2. 修改邮件模板里的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") %>
    
  3. 配置默认URL(推荐,省得每次写host)
    为了不用在每个link_to里重复写host,你可以在环境配置文件里设置全局默认URL:

    • 开发环境:config/environments/development.rb
      config.action_mailer.default_url_options = { host: 'localhost:3000' }
      
    • 生产环境:config/environments/production.rb
      config.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

火山引擎 最新活动