I have a lot of optional fields in Mongoid, like:
field :key, type: String
field :element, type: String
field :rect, type: Array
If I return a json of this model with only one of them filled I get null
values on all the other fields. How can I remove those fields?
My model has nested attributes, which means null values can be on several levels.
Clarifications:
I need a way to remove null fields from the json representation of a model, including null fields in all nested attributes.
Code Example:
1.9.3-p0 :005 > u=Muse.new(:key=>'ram').to_json
=> "{\"_id\":\"4f1ced749c2ee4219d000003\",\"element\":null,\"key\":\"ram\",\"rect\":null}"
As far as I know, there's no such feature in the Mongoid iself. My suggestion would be to go with one of the API generators then:
http://fabrik42.github.com/acts_as_api/
https://github.com/nesquena/rabl
or
https://github.com/rails/jbuilder
This is easy to do if you're using active_model_serializers (check out this Railscast for a quick intro).
For your use case, you can write a
muse_serializer.rb
that looks like this:This will return all non-empty fields present in the current Muse object.
If you are just trying to remove field keys with nil values from query results before sending JSON, say, to the browser, you can simply do this (works in my case):
By default
mongoid
has the ability to remove empty fields. If you let some fields empty,mongoid
will removes them on insert.in the below example, I left out the fields element & rect
and it works perfectly. But if you put a nil value in the field
It gets inserted. I assume that's the exact problem in your code. So you can work around this by converting JSON hash representation using
as_json
and remove the nil fieldsBut to go to the inner levels, you cannot use
as_json
. check the below codeNow you see the field dummy inside the embedded doc house is still with nil. so my best advice is Dont put the nil values in db at all. To do that put a
before_save
callback on your models (embedded too) and remove the empty fields.Also I will show you how to remove nil fields from nested objects too. Use it if there is no other way
We can use
attributes
of mongoid model to get the hash representation of the object including the nested levelsand you have to find is there any Hash inside the mongoid object, if one, we have to use the
reject! {|k,v| v.nil?}
on that Hash tooto put together all
and call this with attributes of the model,
Thats all. Hope it helps