Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Customizing output of JSON

In the controller I have a respond_with like this:

respond_with(@layer1 , @layer2)

The JSON output I need is like this:

{
   "LayerOne": [
      {
         "name": "haha",
         "number":"44"
      }, // more .... 
   ],
  "LayerTwo": [
     {
        "name": "James Bond",
        "score": 20
     } // , ....
  ]
}

So to get the first section I write the serializer like this:

class Layer1Serializer < ActiveModel::Serializer

  attributes :number, :name

  def name
    object.person.name
  end

end

And I change the controller to be like this, so I can pass a ROOT so it shows in the JSON as "LayerOne"

respond_with(@Layer1, root: 'LayerOne')

but remember at the beginning I had two things to pass to controller, so now I can't figure our how to do this for the second section of JSON that says "Layer2"

like image 733
Bohn Avatar asked Feb 17 '23 04:02

Bohn


2 Answers

You can create the following intermediate class:

class BothLayers
  include ActiveModel
  def initialize(layer1,layer2)
    @layer1 = layer1
    @layer2 = layer2
  end
  attr_accessor :layer1, :layer2
end

and the following serializer:

class BothLayersSerializer < ActiveModel::Serializer
  root false
  has_many :layer1, key: "LayerOne"
  has_many :layer2, key: "LayerTwo"
end      

Then in your controller:

    both_layers = BothLayers.new(@layer1,@layer2)
    respond_with( both_layers, serializer: BothLayersSerializer )
like image 200
moonfly Avatar answered Mar 05 '23 03:03

moonfly


Using the JBuilder DSL is an excellent way to solve your problem.

https://github.com/rails/jbuilder

The JSON response you want is implemented as a view, giving you complete control over how it renders.

like image 45
Chris Aitchison Avatar answered Mar 05 '23 03:03

Chris Aitchison