How to add ActiveModel :: Serializer attribute at runtime?

I am trying to allow an API request to specify which fields to return to an object. I can only get an object with the specified fields, but when it is serialized, it throws an error:

ActiveModel::MissingAttributeError (missing attribute: x) 

How can I achieve this function with ActiveModel::Serializer and is this possible?

+5
source share
4 answers

You can remove attributes from the serializer, but they must exist.

 class SomeSerializer < ActiveModel::Serializer attributes :something def attributes super.except(:something) if something end end 
+1
source

This is because the Serializer.attributes method calls each field using the ActiveModel.read_attribute method. This method will apply some validations, such as validates_presence_of in the model definition, which will throw an exception. To avoid this, I give three bad decisions, and after that the best and simplest:

  • Change the model definition, but you will skip your test.
  • Overwrite the ActiveModel.read_attribute method to deal with this behavior, you will get new problems.
  • Overwrite Serializer.attributes and instead of calling super call object.attributes .

But the best option would be to create a new serialization class to avoid, in addition to effects, with the only fields you want. Then specify this in the controller class:

 render json: People.all.reduced, each_serializer: SimplePersonSerializer 

Change 1

The correct answer should be one of Mauricio Linares .

 render json: result.to_json( only: array_of_fields ) 
+1
source

I found this question when I was looking for a good alternative for removing optional fields from a json answer.

The active_model_serializers has a solution for this. You just need to pass the condition 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 such a solution does not exist, but it is available now. :)

Greetings.

0
source

You can customize the attributes by implementing the filter method in your serializer. Please note that I am describing the last stable (at the time of this writing) branch 0.9.x

 class PostSerializer < ActiveModel::Serializer attributes :id, :title, :body, :author def filter(keys) if scope.admin? keys else keys - [:author] end end end 
-1
source

All Articles