我有一个问题,猴子修补部分ActiveJobs。我在config/initializers/extensions/argements.rb中有以下代码
module ActiveJob
module Arguments
TYPE_WHITELIST = [ Date, DateTime, Time, NilClass, Fixnum, Float, String, TrueClass, FalseClass, Bignum ]
end
end基本上,我试图添加对日期/时间对象的基本支持,以便在由ActiveJob创建的ActionMailer#deliver_later中使用。
在加载rails应用程序时,我可以看到我的白名单已经加载,但是当我在邮件程序上调用deliver_later方法时,原始的白名单会覆盖我的修补程序。
#List is correct when app loads
2.1.2 :002 > ActiveJob::Arguments::TYPE_WHITELIST
=> [Date, DateTime, Time, NilClass, Fixnum, Float, String, TrueClass, FalseClass, Bignum]
#List is overridden by default list in ActiveJobs after running #deliver_later
2.1.2 :005 > ActiveJob::Arguments::TYPE_WHITELIST
=> [NilClass, Fixnum, Float, String, TrueClass, FalseClass, Bignum] 我怎样才能使我的修改白名单粘?我很确定这个错误源于原始的ActiveJob::参数,在调用deliver_later之前不会加载,因此在我的修补程序之后加载并重写它,尽管我不知道如何修复它。
发布于 2015-01-26 11:06:07
编辑:不要使用,请参阅https://stackoverflow.com/a/50743819/3293310
这个怎么样?
module ActiveJob
module Arguments
remove_const(:TYPE_WHITELIST)
TYPE_WHITELIST = [ Date, DateTime, Time, NilClass, Fixnum, Float, String, TrueClass, FalseClass, Bignum ]
end
end然后,正如注释中所说的,您应该扩展这个模块:
module ActionMailer
class DeliveryJob < ActiveJob::Base
extend ActiveJob::Arguments
end
end如果您使用的是ruby 2+,一个更好的方法是tu使用改进。不幸的是,您不能用改进的(请阅读Matz的评论)更改常量
发布于 2018-06-07 14:28:46
Pak给出的解决方案可能是危险的!
TL;DR :它在嵌套散列中用时间对象中断,就像反序列化期间一样,它们将作为字符串返回。
因此,在生产中,您实际上希望能够将时间序列化为字符串,并将“时间字符串”反序列化为时间对象。如果只是将时间添加到类型白名单中,序列化和反序列化在常规参数中可能工作得很好,但如果以散列参数发送时间对象,则会中断时间对象,编写失败的测试几乎是不可能的。
相反,按照那里描述的使用GlobalIds对时间类进行分类,这是序列化与ActiveJob一起使用的任何param的常规方法。
基本上,您可以这样修补您的类。
class Time
include GlobalID::Identification
alias_method :id, :to_i
def self.find(seconds_since_epoch)
Time.at(seconds_since_epoch.to_i)
end
end
class ActiveSupport::TimeWithZone
include GlobalID::Identification
alias_method :id, :to_i
def self.find(seconds_since_epoch)
Time.zone.at(seconds_since_epoch.to_i)
end
end因此,可以正确地序列化/反序列化参数。
arguments = [1, { start: Time.now, end: 1.day.ago }]
serialized_arguments = ActiveJob::Arguments.serialize(arguments)
# => [1,
# {"start"=>{"_aj_globalid"=>"gid://my-job-glasses/Time/1528381306"},
# "end"=>{"_aj_globalid"=>"gid://my-job-glasses/Time/1528294906"},
# "_aj_symbol_keys"=>["start", "end"]}]
deserialized_arguments = ActiveJob::Arguments.deserialize(serialized_arguments)
# => [1, {:start=>"2018-06-07T16:21:46.000+02:00", :end=>"2018-06-06T16:21:46.000+02:00"}]
deserialized_arguments.last[:start].class # => Time请注意,这对于将AS:TWZ转换为普通的旧Time有效果,但这比没有aye要好吗?
https://stackoverflow.com/questions/27629697
复制相似问题