How to dynamically add attributes to Active Serializers models

I want to determine the number of attributes to display in my controller.

But I have no idea what to do?

controller.rb

respond_to do |format| if fields # less attributes : only a,c elsif xxx # default attributes else # all attributes : a,c,b,d,... end end 

serializer.rb

 class WeatherLogSerializer < ActiveModel::Serializer attributes :id, :temperature def temperature "Celsius: #{object.air_temperature.to_f}" end end 
+6
source share
2 answers

I would probably do this with a different endpoint for everyone, but you could also pass a different url parameter or something like that. Generally, I think you would like the default to be more limited.

Here is how I would suggest:

controller

Different endpoints for everyone

 render json: objects, each_serializer: WeatherLogAllSerializer 

Allow custom fields

 fields = params[:fields] # Csv string of specified fields. # pass the fields into the scope if fields.present? render json: objects, each_serializer: WeatherLogCustomSerializer, scope: fields else render json: objects, each_serializer: WeatherLogSerializer end 

Three different serializers: all, default, custom

Everything

 class WeatherLogAllSerializer < ActiveModel::Serializer attributes :id, :temperature, :precipitation, :precipitation has_many :measurements def temperature "Celsius: #{object.air_temperature.to_f}" end end 

Default

 class WeatherLogSerializer < ActiveModel::Serializer attributes :id, :temperature def temperature "Celsius: #{object.air_temperature.to_f}" end end 

Custom

 class WeatherLogCustomSerializer < WeatherLogSerializer def attributes data = super if scope scope.split(",").each do |field| if field == 'precipitation' data[:precipitation] = object.precipitation elsif field == 'humidity' data[:humidity] = object.humidity elsif field == 'measurements' data[:measurements] = ActiveModel::ArraySerializer.new(object.measurements) end end end data end end 
+10
source

You can create various serializers and respond_with or render with a custom serializer:

 # serialize an array of WeatherLog(s) render json: objects, each_serializer: WeatherLogSerializer # serialize a WeatherLog render json: object, serializer: WeatherLogSimpleSerializer # just gimme id and temp class WeatherLogSimpleSerializer < ActiveModel::Serializer attributes :id, :temperature def temperature "Celsius: #{object.air_temperature.to_f}" end end # gimme everything class WeatherLogSerializer < ActiveModel::Serializer attributes(*WeatherLog.attribute_names.map(&:to_sym)) end 
+2
source

Source: https://habr.com/ru/post/978221/


All Articles