4

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"

4 Answers 4

6
+300

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 ) 
Sign up to request clarification or add additional context in comments.

1 Comment

brilliant ..... haven't practically tried it yet but just reading what you have here sounds to be a correct solution...plesse update it if you find new tips or tricks about it too. Thanks.
1

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.

2 Comments

Thanks, I already have written it in JBuilder, Wanted to evaluate Serializer and see how hard/easy is it in customizing stuff in compare ot JBuilder.
Well I guess you answered that question ;D
1

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" } ] ] ] 

1 Comment

Oh well this is not using Serializer, This is just the old style as_json .... I have better than that with JBuidler, Here I wanted to evaluate Serializer,
0

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

1 Comment

yep I have watched that, but couldn't solve the question I posted. Any ideas?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.