I've been really digging FastJsonAPI. Works great.
Is it possible to set the set_type
serializer definition on a per-object basis?
i.e. I'm using Rails STI (single table inheritance). I have a mixed set of base objects and derivative objects, and I'd like to have different types for each.
This is a fake example of JSON output I would like:
{
"data": [
{
"attributes": {
"title": "Generic Vehicle"
},
"id": "1",
"type": "vehicle"
},
{
"attributes": {
"title": "Fast Car"
},
"id": "2",
"type": "car"
},
{
"attributes": {
"title": "Slow Car"
},
"id": "3",
"type": "car"
},
{
"attributes": {
"title": "Motorcycle"
},
"id": "4",
"type": "motorcycle"
}
]
}
I do have an object type
attribute I can use, of course, since I'm using STI. But I don't want to use it as an attribute: I want to use it as the outside type
, as in the JSON above.
serializer(s):
class VehicleSerializer
include FastJsonapi::ObjectSerializer
set_type :vehicle # can I tie this to individual objects, right here?
attributes :title
end
class CarSerializer < VehicleSerializer
set_type :car
attributes :title
end
class MotorcycleSerializer < VehicleSerializer
set_type :motorcycle
attributes :title
end
class TruckSerializer < VehicleSerializer
set_type :truck
attributes :title
end
You see, I have some controllers which only pull from a single object type
, and for them, the single CarSerializer
or whatever, works great. The trouble is when I use a controller like this, that aggregates multiple vehicle types in the index method:
require_relative '../serializers/serializers.rb'
class MultiVehiclesController < ApplicationController
def index
@vehicles = Vehicle.where(type: ["Car", "Motorcycle"])
# perhaps there's a way to modify the following line to use a different serializer for each item in the rendered query?
render json: VehicleSerializer.new(@vehicles).serializable_hash
end
def show
@vehicle = Vehicle.find(params[:id])
# I suppose here as well:
render json: VehicleSerializer.new(@vehicle).serializable_hash
end
end
This was not possible in version 1 of FastJsonAPI, which I was using for this. It is now apparently possible as of version 1.2 (although I have not yet tested it).