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
相关产品推荐
相关产品推荐

