Ruby on rails 如何使用Rails和Mongoid将mongodb文档直接返回给客户端

Ruby on rails 如何使用Rails和Mongoid将mongodb文档直接返回给客户端,ruby-on-rails,mongodb,mongoid,Ruby On Rails,Mongodb,Mongoid,给定要在图形中显示的带有日期时间和数据的文档,如何直接返回查询结果,而无需从BSON转换为Ruby,最后转换为JSON 问题:对于BSON中的客户机,时间值被正确存储,但是使用Ruby会将其转换为时间对象,我必须执行time.to_I*1000才能正确存储在返回的JSON中。在任何情况下,我都不需要转换任何数据,所以这感觉像是浪费 我在Heroku+MongoHQ上运行Rails和Mongoid。我想让Rails应用程序对查询进行授权,但不将响应转换为Ruby对象 def show_graph

给定要在图形中显示的带有日期时间和数据的文档,如何直接返回查询结果,而无需从BSON转换为Ruby,最后转换为JSON

问题:对于BSON中的客户机,时间值被正确存储,但是使用Ruby会将其转换为时间对象,我必须执行
time.to_I*1000
才能正确存储在返回的JSON中。在任何情况下,我都不需要转换任何数据,所以这感觉像是浪费

我在Heroku+MongoHQ上运行Rails和Mongoid。我想让Rails应用程序对查询进行授权,但不将响应转换为Ruby对象

def show_graph
  raw_bson = TheModel.all_raw_documents_matching(query_params)
  raw_bson.to_json  
  # Alternatively, this BSON to JSON could be happening client side. 
  # side. Whatever, just don't convert to ruby objects...
end

你的问题有很多观点。 我看到的不是BSON反序列化,而是更关键的
to_json
方法如何处理
Date
Time
ruby对象的序列化

我想到的最简单、最棘手的方法是重写
Time
类的
as_json
方法:

class Time
 def as_json(options={})
    self.to_i * 1000
 end
end

hash = {:time => Time.now}
hash.to_json # "{\"a\":1367329412000}" 
您可以将其放入初始值设定项中。这是一个非常简单的解决方案,但是你必须记住,你应用程序中的每个ruby
时间
对象都将使用你的自定义方法进行序列化。
这可能是好的,也可能不是,很难说,一些gem可能依赖于此

一种更安全的方法是编写一个包装器并调用它,而不是
调用\u 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,因为如果不从ruby
time
class传递,就无法将时间的字符串表示转换为整数表示

下面是一个如何使用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} 
class-Foo
include Mongoid::Document
字段:栏,类型:时间
结束
上课时间
#实例方法mongoize获取对象的一个实例,并将其转换为如何存储在数据库中
蒙哥伊兹酒店
self.to_i*1000
结束
#类方法mongoize从应用程序代码中获取用于在模型上设置的对象,并按照存储在数据库中的方式创建该对象
蒙哥伊兹国防部(o)
o、 蒙哥伊兹
结束
#类方法demongoize将对象作为其在数据库中的存储方式,并负责实例化自定义类型的对象。
def self.demongoize(对象)
对象
结束
结束
Foo.create(:bar=>Time.now)#
Foo.last.as#json{“\u id”=>“518295cebb9ab4e1d2000006”,“bar”=>1367512526}

这是ruby对象,正是我想要避免的。我更新了答案,提供了一个示例。希望能帮助您。我看到使用mongo控制台在MongoDB中的原始时间是
“更新时间”:ISODate(“2012-10-26T06:47:27.603Z”)
。您的答案是“您不能直接返回,每个值必须是一个ruby对象”。不是我想要的答案。然而,有趣的方法是,将值存储为您想要检索的值(本例中为整数毫秒)。我决不会那样打发时间,但我明白了。