While working with Rails and Mongoid, I encountered a challenge related to serialization. Jbuilder serialized record’s ID as a Hash.
For example, here is a simplified definition of one of the Mongo models:
1
2
3
4
5
6
7
8
9
10
11
12
class Book
include Mongoid::Document
include Mongoid::Timestamps
field :genre, type: String
field :title, type: String
field :author, type: String
field :pages, type: Integer
index({_id: 'hashed'})
end
And this is how JBuilder was instructed to serialize a Book
record:
1
json.(book, :id, :genre, :title, :author, :pages)
When the create
endpoint was hit to add a record to the collection, this was the response from the controller:
1
2
3
4
5
6
7
8
9
{
"_id": {
"$oid": "657c90837c49b1464b30e29e"
},
"genre": "scifi",
"title": "The Time Machine",
"author": "H. G. Wells",
"pages": 112
}
When using Mongoid in a Rails application, the BSON
object representing the ID is serialized as a nested hash with a “$oid” key. While this format is valid BSON
, it doesn’t look pretty, and when interacting with external systems they may expect a simpler representation. Fortunately, resolving this serialization issue is straightforward. The key is to override the default BSON object serialization behavior.
We create a file named mongoid.rb
in the config/initializers
directory. The name of the file is arbitrary. You may choose to name it to whatever you like.
Inside mongoid.rb
, add the following piece of code:
1
2
3
4
5
6
module BSON
class ObjectId
alias :to_json :to_s
alias :as_json :to_s
end
end
This code overrides the to_json
and as_json
methods for the ObjectId
class, ensuring that the BSON object is represented as a string during serialization.
Now, restart the rails server for initializers to load, and voila, the JSON represenation of the object becomes
1
2
3
4
5
6
7
{
"id": "657c90837c49b1464b30e29e",
"genre": "scifi",
"title": "The Time Machine",
"author": "H. G. Wells",
"pages": 112
}
Comments