'Have to_json return a mongoid as a string
In my Rails API, I'd like a Mongo object to return as a JSON string with the Mongo UID as an "id" property rather than as an "_id" object.
I want my API to return the following JSON:
{
"id": "536268a06d2d7019ba000000",
"created_at": null,
}
Instead of:
{
"_id": {
"$oid": "536268a06d2d7019ba000000"
},
"created_at": null,
}
My model code is:
class Profile
include Mongoid::Document
field :name, type: String
def to_json(options={})
#what to do here?
# options[:except] ||= :_id #%w(_id)
super(options)
end
end
Solution 1:[1]
You can monkey patch Moped::BSON::ObjectId
:
module Moped
module BSON
class ObjectId
def to_json(*)
to_s.to_json
end
def as_json(*)
to_s.as_json
end
end
end
end
to take care of the $oid
stuff and then Mongoid::Document
to convert _id
to id
:
module Mongoid
module Document
def serializable_hash(options = nil)
h = super(options)
h['id'] = h.delete('_id') if(h.has_key?('_id'))
h
end
end
end
That will make all of your Mongoid objects behave sensibly.
Solution 2:[2]
For guys using Mongoid 4+ use this,
module BSON
class ObjectId
alias :to_json :to_s
alias :as_json :to_s
end
end
Solution 3:[3]
You can change the data in as_json
method, while data is a hash:
class Profile
include Mongoid::Document
field :name, type: String
def as_json(*args)
res = super
res["id"] = res.delete("_id").to_s
res
end
end
p = Profile.new
p.to_json
result:
{
"id": "536268a06d2d7019ba000000",
...
}
Solution 4:[4]
Use for example:
user = collection.find_one(...)
user['_id'] = user['_id'].to_s
user.to_json
this return
{
"_id": "54ed1e9896188813b0000001"
}
Solution 5:[5]
class Profile
include Mongoid::Document
field :name, type: String
def to_json
as_json(except: :_id).merge(id: id.to_s).to_json
end
end
Solution 6:[6]
If you don't want to change default behavior of MongoId, just convert result of as_json.
profile.as_json.map{|k,v| [k, v.is_a?(BSON::ObjectId) ? v.to_s : v]}.to_h
Also, this convert other BSON::ObjectId
like user_id
.
Solution 7:[7]
# config/initializers/mongoid.rb
# convert object key "_id" to "id" and remove "_id" from displayed attributes on mongoid documents when represented as JSON
module Mongoid
module Document
def as_json(options={})
attrs = super(options)
id = {id: attrs["_id"].to_s}
attrs.delete("_id")
id.merge(attrs)
end
end
end
# converts object ids from BSON type object id to plain old string
module BSON
class ObjectId
alias :to_json :to_s
alias :as_json :to_s
end
end
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | mu is too short |
Solution 2 | Ronak Jain |
Solution 3 | |
Solution 4 | Juan Labrador |
Solution 5 | |
Solution 6 | hiroshi |
Solution 7 | Hackeron |