使用Sidekiq适配器的ActiveJob传递Class、Date参数时报序列化错误
你遇到的报错是Rails版本不匹配导致的:你当前使用的Rails版本为5.0.7,该版本的ActiveJob默认支持的参数类型仅包含字符串、数值、布尔值、nil、数组、哈希、带有GlobalID的Active Record对象,Class和Date类型的默认序列化支持是在后续更高版本的Rails中才加入的,你查阅的官方文档对应更高Rails版本,和你当前环境的特性不一致。
方案1:调整传参逻辑(兼容性最好,无需额外配置)
- 处理Class类型参数:不直接传递类对象,改为传递类的字符串名称,在Job执行时调用
constantize方法还原为类 - 处理Date类型参数:传递前转换为ISO8601格式字符串或者时间戳,在Job执行时再转换回Date类型
示例代码:
# 调用Job StripeTransactionsSyncJob.perform_later('Stripe::SyncCharges', nil, 3.days.ago.to_date.iso8601) # Job内部执行逻辑 def perform(sync_class_name, empty_arg, date_str) sync_class = sync_class_name.constantize sync_date = Date.parse(date_str) # 原有业务逻辑 end
方案2:自定义序列化器(无需修改现有传参代码)
你可以通过自定义ActiveJob序列化器,全局添加对Class和Date类型的支持,添加初始化文件即可:
# config/initializers/active_job_custom_serializers.rb # 自定义Date序列化器 class DateSerializer < ActiveJob::Serializers::ObjectSerializer def serialize?(argument) argument.is_a?(Date) end def serialize(date) super(date.iso8601) end def deserialize(hash) Date.parse(hash["value"]) end end # 自定义Class序列化器 class ClassSerializer < ActiveJob::Serializers::ObjectSerializer def serialize?(argument) argument.is_a?(Class) end def serialize(klass) super(klass.name) end def deserialize(hash) hash["value"].constantize end end # 注册序列化器 Rails.application.config.after_initialize do ActiveJob::Serializers.add_serializers DateSerializer, ClassSerializer end
添加后重启服务即可直接传Class和Date类型参数。
内容的提问来源于stack exchange,提问作者Amit Patel
相关产品推荐
相关产品推荐

