I am trying to allow an API request to specify what fields to return on an object. I can retrieve the object with only the fields specified, but when it is serialized, it throws an error:
ActiveModel::MissingAttributeError (missing attribute: x)
How can I achieve this functionality with ActiveModel::Serializer
and is it possible?
I've found this question while searching for a good alternative to remove optional fields from the json response.
The gem active_model_serializers
does have a solution for this. You just need to pass a conditional to the attribute
method in the serializer declaration.
class MySelectiveSerializer < ActiveModel::Serializer
attributes :id, :anything
attribute :something, if: -> { object.something.present? }
end
Perhaps 3 years ago a solution like this didn't exist, but it is available now. :)
Cheers.
This happens because the Serializer.attributes
method call each field using the ActiveModel.read_attribute
method. This method will apply some validations, like validates_presence_of
at the model's definition, that will raise the exception. To avoid it I give three bad solutions and after a better and simple one:
ActiveModel.read_attribute
to handle this behavior, you will get new challenges.Serializer.attributes
and instead of call super, call object.attributes
.But the best option will be create a new serialize class, to avoid besides effects, with the only fields that you want. Then specify this at the controller class:
render json: People.all.reduced, each_serializer: SimplePersonSerializer
Edit 1
The right answer should be the one from Maurício Linhares.
render json: result.to_json( only: array_of_fields )
You can remove attributes from serializer, but they should exist.
class SomeSerializer < ActiveModel::Serializer
attributes :something
def attributes
super.except(:something) if something
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With