I'm trying to build a JSON API style API using AM::Serializer. I'm running into an issue with sideloading.
I want to be able to build JSON that looks like:
{
"primaries": [{
"id": 123,
"data": "Hello world.",
"links": {
"secondaries": [ 1, 2, 3 ]
}
}],
"linked" : {
"secondaries": [
{
"id": 1,
"data": "test1"
},
{
"id": 2,
"data": "test2"
},
{
"id": 3,
"data": "test3"
}
]
}
}
The code I've been able to come up with looks like:
class PrimarySerializer < ActiveModel::Serializer
attributes :id, :data
has_many :secondaries, key: :secondaries, root: :secondaries
embed :ids, include: true
end
Which generates JSON that looks like:
{
"primaries": [{
"id": 123,
"data": "Hello world.",
"secondaries": [ 1, 2, 3 ]
}],
"secondaries": [
{
"id": 1,
"data": "test1"
},
{
"id": 2,
"data": "test2"
},
{
"id": 3,
"data": "test3"
}
]
}
Is there a way to override the location of the in-element secondaries
and sideloaded secondaries
such that they live in child nodes link
and linked
?
The above code is an abstraction of the actual code and may not work. Hopefully it illustrates the point sufficiently.
Thanks!
ActiveModel Serializers can do this. The problem is that the built-in association methods are to restrictive. Instead you must build up the links
& linked
parts manually.
(This answer refers to the stable 0.8.1 version of ActiveModel Serializers)
Here's a Gist with a complete JSON-API solution https://gist.github.com/mars/97a637560109b8ddfb27
Example:
class ExampleSerializer < JsonApiSerializer # see Gist for superclass
attributes :id, :name, :links
def links
{
things: object.things.map(&:id),
whatzits: object.whatzits.map(&:id)
}
end
def as_json(*args)
hash = super(*args)
hash[:linked] = {
things: ActiveModel::ArraySerializer.new(
object.things,
each_serializer: ThingsSerializer
).as_json,
whatzits: ActiveModel::ArraySerializer.new(
object.whatzits,
each_serializer: WhatzitsSerializer
).as_json
}
hash
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With