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

升级Ruby至3.2.2后mail 2.8.1的deliver_now方法传参报错

Ruby 3.2.2 + Rails 6.1.7 + Mail 2.8.1:deliver_now调用时的关键字参数错误

问题场景

基于Rails 6.1.7的项目,将Ruby升级至3.2.2后,使用mail 2.8.1版本时,执行邮件发送代码:

TestMailer.test_mail(one: foo, two: bar).deliver_now

抛出如下错误:

wrong number of arguments (given 1, expected 0; required keywords: one, two) (ArgumentError)

对应的邮件方法定义为:

def test_mail(one:, two:)
    attach_files([one.last.pdf_path.to_s]) if two

    send_mail(one: one)
end

将mail锁定为2.7.1版本,同时Ruby仅升级至3.0.4时,代码可正常运行。

原因分析

Ruby 3.0及以上版本对关键字参数的处理逻辑做了调整,而mail 2.8.1在与Rails 6.1.7、Ruby 3.2.2配合时,内部处理deliver_now流程中存在参数传递的兼容性问题——gem可能错误地将调用时传入的关键字参数封装成了单个哈希位置参数,导致邮件方法接收参数时触发校验错误。

解决方案

  • 降级mail gem:将Gemfile中的mail版本锁定为2.7.1,同时可暂时维持Ruby版本在3.0.4,直接恢复兼容性。
  • 升级Rails补丁版本:将Rails升级至6.1.x分支的最新补丁版(如6.1.7.6及以上),Rails官方后续补丁修复了部分与Ruby 3.2及mail gem的参数兼容问题。
  • 修改邮件方法参数兼容:如果需要保留Ruby 3.2.2和mail 2.8.1,可修改邮件方法的参数接收逻辑,兼容两种参数传递形式:
def test_mail(*args, one:, two:)
  # 兼容可能被封装成哈希的参数
  if args.present?
    one = args.first[:one] || one
    two = args.first[:two] || two
  end
  attach_files([one.last.pdf_path.to_s]) if two

  send_mail(one: one)
end

注意:此方案需要全面测试,避免影响其他邮件调用场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 02:42:17