Reputation: 26919
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"
Upvotes: 4
Views: 2466
Reputation: 3195
create a new hash and pass your array values into it.
respond_with({:LayerOne => @layer1.as_json(:only => [:name, :percentage]), :LayerTwo => @layer2.as_json(:only => [:name, :off_target_by])})
i got this json :
{
"LayerOne": [
{
"name": "layer1",
"percentage": "10.11"
},
{
"name": "layer 1 bis",
"percentage": "1212.0"
}
],
"LayerTwo": [
{
"name": "layer 2",
"off_target_by": 2
},
{
"name": "layer 2 bis",
"off_target_by": 9
}
]
}
hope it helps :)
EDIT 2 :
You can create an array serializer to pass your variables :
class LayerArraySerializer < ActiveModel::ArraySerializer
self.root = false
end
and in your view :
respond_with({:LayerOne => @layer1 , :LayerTwo => @layer2}, :serializer => LayerArraySerializer)
json print :
[
[
"LayerOne",
[
{
"percentage": "10.11",
"name": "layer1"
},
{
"percentage": "1212.0",
"name": "layer 1 bis"
}
]
],
[
"LayerTwo",
[
{
"off_target_by": 2,
"name": "layer 2"
},
{
"off_target_by": 9,
"name": "layer 2 bis"
}
]
]
]
Upvotes: 1
Reputation: 1820
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 )
Upvotes: 6
Reputation: 4654
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.
Upvotes: 1
Reputation: 13181
Railcasts has an excellent video+text tutorial on AR Serializer, I'm sure you'll find your answer there
http://railscasts.com/episodes/409-active-model-serializers
Upvotes: 0