I have 3 models: a parent class Event, 2 child classes CameraEvent and WeatherEvent. In my controller, I would do render json: @events. How do I configure AMS such that it will use CameraEventSerializer for CameraEvent and WeatherEventSerializer for WeatherEvent? Thanks.
@jeffrey008 AMS doesn't do STI, ActiveRecord does. STI is an implementation detail that backs multiple classes by one table. Your question should really be, 'how do I serialize a collection of different classes?'.
What have you tried?
Yes the question should be 'how do I serialize a collection of different classes?'.
I should show some code to explain better:
# controllers/event_controller.rb
def index
render json: @events, each_serializer: serializer
end
def serializer
if type == "camera"
return CameraEventSerializer
end
if type == "weather"
return WeatherEventSerializer
end
end
Sadly, this doesn't work because I don't know the event's type. I wish I could do something like passing each event's type into my serializer method.
render json: @events, each_serializer: serializer(@events[index].type)
I wish I could do something like passing each event's type into my serializer method.
Yeah, that would be nice. I wish we supported a way to specify mapping objects to serializers.
You can still serialize things yourself. It's less magical, but there's no shame in that :)
You can still serialize things yourself.
Do you mean something like this?
def index
@events.each do |e|
if e.type == "camera"
return CameraEventSerializer.new(e).to_json
end
if e.type == "weather"
return WeatherEventSerializer.new(e).to_json
end
end
render json: @events
end
Please correct me if I'm wrong. Thanks.
I propose that each_serializer can take a Symbol or a block as a value, then people can do whatever they would like to in the block.
@jeffrey008 Currently in AMS you will have to rely on serializer inference for polymorphic associations.
Hi @beauby In my case there is no association. @events is an array of event with different types. I want AMS to use the correct serializer based on event.type.
@jeffrey008 @beauby @bf4 Any updates on how to properly serialize a collection of different class models identified by type?
@nguyenj It's unclear what version of AMS you're on or what you mean by 'properly' in the context of this issue. There haven't been any feature changes to 0.9. Please open a new issue if the discussion here is not sufficient.
Hi @bf4 I'm using version AMS 0.9 since this issue is regarding AMS v0.9.
As for the help and clarification that I am asking for is how can I use a different serializer for each item in a collection depending on the .type attribute of the item. I can't seem to find any documentation or examples to illustrate this scenario.
Thanks!
Ah nvm, I see that in 0.10, there's ActiveModel::Serializer::CollectionSerializer that I can use.
@nguyenj Based on discussion above, would be something like (not tested code):
events.group_by(:type).map { |type, events|
case type
when 'CameraEvent' then CameraEventSerializer.new(events).as_json
when 'WeatherEvent' then WeatherEventSerializer.new(events).as_json
else fail ArgumentError, "Unhandled event type '#{type}'"
end
}
@bf4 I think that might work, I’ll give it a whirl. Thanks for being super responsive.
@bf4 Thanks! This works; however, the index is messy–is there a way for this logic to be housed in a base serializer?
Ideally, it was be nice the logic housed in an EventSerializer so that in the controller you'll just need to define:
render json: @event(s), each_serializer: EventSerializer, status: :(okay|created)
EventSerializer would determine which serializer to use depending on the type attribute of the object.
Sure. How about
EventsSerializer = Struct.new(:events) do
def as_json
#logic from controller
end
def to_json; JSON.dump(as_json); end
end
And
render json: EventsSerializer.new(events)
B mobile phone
On Oct 12, 2017, at 8:58 AM, John notifications@github.com wrote:
Ideally, it was be nice to be housed in an EventSerializer so that in the controller you'll just need to define render json: @event(s), each_serializer: EventSerializer. EventSerializer would determine which serializer to use depending on the type attribute of the object.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
Most helpful comment
@nguyenj Based on discussion above, would be something like (not tested code):