DEV Community

RobL
RobL

Posted on • Originally published at robl.me

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 
Enter fullscreen mode Exit fullscreen mode

GET /api/v1/me

{ "data": { "id": "1a2b3c4d000001", "type": "users", "attributes": { "uuid": "aaaaaaaabbbbbbbbccccccccc", "email": "rob.lacey@buttonmoon.co.uk", "full_name": "Mr Rob Lacey" } } } 
Enter fullscreen mode Exit fullscreen mode

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" } } ] } } 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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 ] 
Enter fullscreen mode Exit fullscreen mode

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 
Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)