You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 8 Mailer变量传递失败:如何正确传递对象?

Rails 8 邮件器传递对象的正确方式

问题根源

你遇到的问题出在两个关键环节:

  • 邮件器中获取with传递参数的方式错误,Rails不会自动将with的参数转为实例变量或局部变量
  • 动态SMTP配置的delivery_options没有正确关联到邮件发送流程

修正方案

1. 正确获取with传递的参数

在Rails邮件器中,with方法传递的参数会被封装到params对象里,需要通过params[:key]访问,也可以手动赋值给实例变量方便后续使用。

2. 正确配置动态SMTP选项

必须将SMTP配置作为mail方法的delivery_method_options参数传入,否则配置不会生效。

修正后的邮件器代码

class CustomMailer < ApplicationMailer
  def message_email
    # 从params中取出传递的对象,赋值给实例变量
    @shop = params[:shop]
    @message = params[:message]

    # 验证参数是否获取成功(调试用,可删除)
    puts @shop.inspect
    puts '-'
    puts params[:shop].inspect

    # 发送邮件时传入动态SMTP配置
    mail(
      to: @shop.to_default,
      subject: "some subject",
      delivery_method_options: {
        user_name: @shop.smtp_user,
        password: @shop.smtp_password,
        address: @shop.smtp_host
      }
    )
  end
end

进阶优化(可选)

如果多个邮件方法需要共享参数获取逻辑,可以用before_action提取公共代码:

class CustomMailer < ApplicationMailer
  before_action :load_shop_and_message

  def message_email
    mail(
      to: @shop.to_default,
      subject: "some subject",
      delivery_method_options: smtp_options
    )
  end

  private

  def load_shop_and_message
    @shop = params[:shop]
    @message = params[:message]
  end

  def smtp_options
    {
      user_name: @shop.smtp_user,
      password: @shop.smtp_password,
      address: @shop.smtp_host
    }
  end
end

控制器代码无需修改,保持原有调用方式即可:

if @message.save
  puts @shop.inspect
  CustomMailer.with(shop: @shop, message: @message).message_email.deliver_later
end

内容的提问来源于stack exchange,提问作者Jerome

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 11:20:08