你的问题有很多观点。而不是 BSON 反序列化,我看到该to_json
方法如何处理ruby 对象的序列Date
化更为关键。Time
我想到的最简单,最棘手的方法是覆盖类的as_json
方法Time
:
class Time
def as_json(options={})
self.to_i * 1000
end
end
hash = {:time => Time.now}
hash.to_json # "{\"a\":1367329412000}"
您可以将其放入初始化程序中。这是一个非常简单的解决方案,但您必须记住,Time
您的应用程序中的每个 ruby 对象都将使用您的自定义方法进行序列化。这可能很好,也可能不好,真的很难说,一些宝石可能依赖于此,或不依赖于此。
一种更安全的方法是编写一个包装器并调用它而不是to_json
:
def to_json_with_time
converted_hash = self.attributes.map{|k,v| {k => v.to_i * 1000 if v.is_a?(Time)} }.reduce(:merge)
converted_hash.to_json
end
最后,如果你真的想重写 Mongoid 序列化和反序列化对象的方式,并且如果你想跳过 BSON 过程,你必须定义mongoize
和demongoize
方法。在这里您可以找到文档:自定义字段序列化
**更新**
问题是序列化而不是反序列化。如果你从查询中得到一个原始 BSON,你仍然有一个Time
ruby 对象的字符串表示。您不能将 BSON 直接转换为 JSON,因为如果不从 rubyTime
类传递,就无法将时间的字符串表示形式转换为整数表示形式。
这是一个如何使用 Mongoid 自定义字段序列化的示例。
class Foo
include Mongoid::Document
field :bar, type: Time
end
class Time
# The instance method mongoize take an instance of your object, and converts it into how it will be stored in the database
def mongoize
self.to_i * 1000
end
# The class method mongoize takes an object that you would use to set on your model from your application code, and create the object as it would be stored in the database
def self.mongoize(o)
o.mongoize
end
# The class method demongoize takes an object as how it was stored in the database, and is responsible for instantiating an object of your custom type.
def self.demongoize(object)
object
end
end
Foo.create(:bar => Time.now) #<Foo _id: 518295cebb9ab4e1d2000006, _type: nil, bar: 1367512526>
Foo.last.as_json # {"_id"=>"518295cebb9ab4e1d2000006", "bar"=>1367512526}