JBuilder Arrays and non-collections
JBuilder may not be the most efficient way to present an API but for simple cases it works pretty well. Our JSON-API standardized API could return the current authenticated user like so.
show.json.jbuilder
json.data do
json.id current_user.id
json.type 'users'
json.attributes do
json.(current_user, :uuid, :email, :full_name)
end
end
/api/v1/me
{
"data": {
"id": "1a2b3c4d000001",
"type": "users",
"attributes": {
"uuid": "aaaaaaaabbbbbbbbccccccccc",
"email": "rob.lacey@buttonmoon.co.uk",
"full_name": "Mr Rob Lacey"
}
}
Ideally I want to now add an included block so that can included related objects such as Tenant. Something like
{
"data": {
"id": "1a2b3c4d000001",
"type": "users",
"attributes": {
"uuid": "aaaaaaaabbbbbbbbccccccccc",
"email": "rob.lacey@buttonmoon.co.uk",
"full_name": "Mr Rob Lacey"
},
"included": [
{
"id": "1",
"type": "tenants",
"attributes": {
"name": "superadmin"
}
}
]
}
}
All of the JBuilder examples talk in terms of Arrays of objects being built from a collection. Most of the time they probably are.
json.array! @comments do |comment|
next if comment.marked_as_spam_by?(current_user)
json.body comment.body
json.author do
json.first_name comment.author.first_name
json.last_name comment.author.last_name
end
end
Or
json.array! @people, :id, :name
But not always. If we want to add an array that is made up or arbitrary builder blocks, you find yourself thinking in terms of doing.json.included do
json.merge! do
json.id current_user.tenant_id
json.type 'tenants'
json.attributes do
json.(current_user.tenant, :name)
end
end
end
json.included [
json.data do
json.id current_user.tenant_id
json.type 'tenants'
json.attributes do
json.(current_user.tenant, :name)
end
end
end
]
Neither of which work, turns out the way to do it is using the undocumented child! method.
json.data do
json.id current_user.id
json.type 'users'
json.attributes do
json.(current_user, :uuid, :email, :full_name)
end
json.included do
json.child! do
json.id current_user.tenant_id
json.type 'tenants'
json.attributes do
json.(current_user.tenant, :name)
end
end
end
end
Think I’ll do a pull request for the README as this took me a while to work out.
https://github.com/rails/jbuilder/pull/507