active_model_serializers
active_model_serializers copied to clipboard
Specifying attributes of associated resources to be rendered excludes parent fields
Expected behavior vs actual behavior
I have a scenario similar to that outlined in the documentation. I want to restrict the fields serialized on my associations via the controller whilst retaining the fields specified in the serializer for the parent.
Example:
render json: @posts, include: 'comments', fields: [ comments: ['content', 'created_at'] ]
In this example it will correctly serialize only the content and created_at fields for the comments, but it will no longer return any fields for the posts.
I narrowed this down to the fields_to_fieldset method on the ActiveModelSerializers::Adapter::Attributes. The method will always add an empty array for the parent model because of line 32, and the empty array is by default interpreted to return no fields:
relationship_fields.merge!(serializer.json_key.to_sym => resource_fields)
I appreciate the documentation I linked only mentions this syntax works for json_api, so perhaps this behaviour is intended, but I would appreciate being able to override it because currently the only workaround I have found is to specify all the attributes in the serializer again in the fields.
Environment
ActiveModelSerializers Version (commit ref if not on tag):
I tested this with version 10.0.0 and 10.0.13 - both had the same issue.
Integrated application and version (e.g., Rails, Grape, etc):
Rails: 7.0.4 Ruby: 3.0.5
For anyone looking for a workaround that doesn't involve manually listing all the attributes from the serializer in the fields, the following should work:
attributes = PostSerializer._attributes
render json: @posts, include: 'comments', fields: [ *attributes, comments: ['content', 'created_at'] ]
In addition, for nested relation of relations, the following will also work:
attributes = PostSerializer._attributes
render json: @posts, include: [:comments, 'comments.tags'], fields: [ *attributes, comments: ['content', 'created_at'], tags: ['name'] ]