daveanderson88
daveanderson88

Reputation: 347

How to use Jbuilder to display parent info with child information nested underneath

I am using jbuilder in rails to generate some JSON in a rails app. In my models, 'od_items' belong to 'od', and 'ods' belong to 'sophead'.

I want to display each 'od' of the 'sophead', and then nested under each of these, I want to display each of the 'od_items' that belong to the 'od'.

Here is my code so far:

json.ods @sophead.ods do |od|
  json.od od
  json.od_items od.od_items do |od_item|
    json.od_item od_item
  end
end

This is outputting the following JSON:

ods: [
{
od: {
id: 51,
sophead_id: 386,
created_at: "2018-03-21T15:28:48.802Z",
updated_at: "2018-03-21T15:28:48.802Z",
status: "Open"
},
od_items: [
{
od_item: {
id: 285,
od_id: 51,
qty: "1.0",
part: "CARRIAGE CHARGE",
description: "Simpson Carriage Charge",
created_at: "2018-03-21T15:28:48.823Z",
updated_at: "2018-03-21T15:28:48.823Z"
}
},
{
od_item: {
id: 284,
od_id: 51,
qty: "1.0",
part: "MISCELLANEOUS",
description: "Split Box Charge",
created_at: "2018-03-21T15:28:48.816Z",
updated_at: "2018-03-21T15:28:48.816Z"
}
}
]
}
],

The problem is that I want 'od_items' to be nested inside the 'od' that it relates to, instead it appears next to it.

This should be pretty simple to sort out, but I cant find anything online.

(First question on Stack overflow - Thanks very much in advance)

Upvotes: 0

Views: 579

Answers (1)

mabe02
mabe02

Reputation: 2734

If your @sophead.ods is a collection of hashes, you can easily achieve it merging the od element with its od_items:

json.ods @sophead.ods do |od|
  json.od od.merge(od_items: od.od_items)
end

Since it seems that these are ActiveRecords:

json.ods @sophead.ods do |od|
  json.od od.as_json.merge(od_items: od.od_items.map(&:as_json))
end

According to the README, another way to obtain the same result is to use json.merge!:

json.ods @sophead.ods do |od|
  json.od do
    json.id od.id
    json.sophead_id od.sophead_id
    json.created_at od.created_at
    json.updated_at od.updated_at
    json.status od.status
    json.merge! { od_items: od.od_items.as_json}
end

Another approach which assures better performances would be to use ActiveModelSerializer instead.

class OdSerializer < ActiveModelSerializers::Model
  attributes :id, :sophead_id, :created_at, :updated_at, :status
  has_many :od_items, serializer: OdItemSerializer
end

class OdItemSerializer < ActiveModelSerializers::Model
  attributes :id, :od_id, :qty, :part, :description, :created_at, :updated_at
end

# And in the controller
render json: @sophead.ods, each_serializer: OdSerializer

Upvotes: 1

Related Questions