【问题标题】:BSON::InvalidDocument: Cannot serialize an object into BSONBSON::InvalidDocument:无法将对象序列化为 BSON
【发布时间】:2012-05-08 01:25:59
【问题描述】:

我正在尝试关注http://mongotips.com/b/array-keys-allow-for-modeling-simplicity/

我有一个 Story 文档和一个 Rating 文档。用户将对故事进行评分,因此我想创建与用户评分的多重关系:

class StoryRating
  include MongoMapper::Document

  # key <name>, <type>
  key :user_id, ObjectId
  key :rating, Integer
  timestamps!

end

class Story
  include MongoMapper::Document

  # key <name>, <type>
  timestamps!
  key :title, String
  key :ratings, Array, :index => true

  many :story_ratings, :in => :ratings

end

然后

irb(main):006:0> s = Story.create  
irb(main):008:0> s.ratings.push(Rating.new(user_id: '0923ksjdfkjas'))  
irb(main):009:0> s.ratings.last.save  
=> true  
irb(main):010:0> s.save  
BSON::InvalidDocument: Cannot serialize an object of class StoryRating into BSON.  
    from /usr/local/lib/ruby/gems/1.9.1/gems/bson-1.6.2/lib/bson/bson_c.rb:24:in `serialize' (...)

为什么?

【问题讨论】:

    标签: mongodb mongomapper


    【解决方案1】:

    您应该使用关联“story_rating”方法进行推送/追加,而不是内部“评级”Array.push 来获得您想要的内容,请遵循 John Nunemaker 的“Array Keys Allow For Modeling Simplicity”讨论。不同之处在于,使用关联方法时,MongoMapper 会将 BSON::ObjectId 引用插入到数组中,而后者是您将 Ruby StoryRating 对象推送到数组中,而底层驱动程序驱动程序无法对其进行序列化。

    这是一个适合我的测试,它显示了差异。希望这会有所帮助。

    测试

    require 'test_helper'
    
    class Object
      def to_pretty_json
        JSON.pretty_generate(JSON.parse(self.to_json))
      end
    end
    
    class StoryTest < ActiveSupport::TestCase
      def setup
        User.delete_all
        Story.delete_all
        StoryRating.delete_all
        @stories_coll = Mongo::Connection.new['free11513_mongomapper_bson_test']['stories']
      end
    
      test "Array Keys" do
        user = User.create(:name => 'Gary')
        story = Story.create(:title => 'A Tale of Two Cities')
        rating = StoryRating.create(:user_id => user.id, :rating => 5)
        assert_equal(1, StoryRating.count)
        story.ratings.push(rating)
        p story.ratings
        assert_raise(BSON::InvalidDocument) { story.save }
        story.ratings.pop
        story.story_ratings.push(rating) # note story.story_ratings, NOT story.ratings
        p story.ratings
        assert_nothing_raised(BSON::InvalidDocument) { story.save }
        assert_equal(1, Story.count)
        puts Story.all(:ratings => rating.id).to_pretty_json
      end
    end
    

    结果

    Run options: --name=test_Array_Keys
    
    # Running tests:
    
    [#<StoryRating _id: BSON::ObjectId('4fa98c25e4d30b9765000003'), created_at: Tue, 08 May 2012 21:12:05 UTC +00:00, rating: 5, updated_at: Tue, 08 May 2012 21:12:05 UTC +00:00, user_id: BSON::ObjectId('4fa98c25e4d30b9765000001')>]
    [BSON::ObjectId('4fa98c25e4d30b9765000003')]
    [
      {
        "created_at": "2012-05-08T21:12:05Z",
        "id": "4fa98c25e4d30b9765000002",
        "ratings": [
          "4fa98c25e4d30b9765000003"
        ],
        "title": "A Tale of Two Cities",
        "updated_at": "2012-05-08T21:12:05Z"
      }
    ]
    .
    
    Finished tests in 0.023377s, 42.7771 tests/s, 171.1084 assertions/s.
    
    1 tests, 4 assertions, 0 failures, 0 errors, 0 skips
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-23
      • 2022-01-24
      • 1970-01-01
      • 2015-07-31
      • 1970-01-01
      • 1970-01-01
      • 2018-06-09
      • 1970-01-01
      相关资源
      最近更新 更多