Ruby下nil调用ascii_only?错误,向Mailer传递message参数失败如何解决
问题根因
你遇到的报错核心是ActionMailer 内置保留了 @message 实例变量名,用于指代当前正在构建的 Mail::Message 邮件对象。你在邮件发送器方法里手动把@message赋值为自定义的文本参数,直接覆盖了内部的邮件实例对象,后续Rails处理邮件元数据(比如主题、收件人编码)时,原本要调用邮件对象的ascii_only?方法,结果拿到的是你赋值的自定义内容(甚至在内部逻辑中被重置为nil),就触发了对应的NoMethodError。
你移除@message参数后没有了覆盖操作,内置邮件对象正常初始化,所以邮件就能正常发送。
解决方法
只需要修改自定义参数的变量名,避开@message这个保留名即可,步骤如下:
- 修改邮件发送器的方法,把自定义的消息参数对应的实例变量改名,比如改成
@custom_message或者@gift_note:
def welcome(consumer, gifted_consumer, roleshopuser, gifted_consumer_transaction, custom_message) @consumer = consumer @user = gifted_consumer @roleshopuser = roleshopuser @transaction = gifted_consumer_transaction # 不要用@message作为变量名,改用自定义的非保留名 @custom_message = custom_message mail(to: @user.email, subject: (t('mailergift.title') + ' ' + @roleshopuser.shop.name ) ) end
- 对应修改邮件视图模板里的引用,把所有
@message替换成你改后的名字,比如@custom_message。 - 控制器调用不需要改参数传递逻辑,控制器里的
@message和mailer里的变量名作用域不同不会冲突,当然你也可以统一改名避免混淆:
GiftMailer.welcome(@consumer, @gifted_consumer, @roleshopuser, @gifted_consumer_transaction, @message).deliver
额外验证
如果改完变量名还有报错,可以再加两层排查:
- 检查
I18n.t('mailergift.title')返回值是否存在,避免翻译缺失返回nil - 检查
@roleshopuser.shop.name是否真的有值,避免关联数据为空
按照你给出的调试信息,移除@message就正常,基本可以确定是变量名冲突的问题。
内容的提问来源于stack exchange,提问作者Jerome
相关产品推荐
相关产品推荐

