自定义JSON的输出

时间:2013-03-13 23:14:51

标签: ruby-on-rails

在控制器中,我有一个像这样的响应:

respond_with(@layer1 , @layer2)

我需要的JSON输出是这样的:

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

所以为了得到第一部分我写这样的序列化器:

class Layer1Serializer < ActiveModel::Serializer

  attributes :number, :name

  def name
    object.person.name
  end

end

我将控制器改为这样,所以我可以传递一个ROOT,因此它在JSON中显示为“LayerOne”

respond_with(@Layer1, root: 'LayerOne')

但请记住,在开始时我有两件事要传递给控制器​​,所以现在我无法想象我们如何为JSON的第二部分说“Layer2”

4 个答案:

答案 0 :(得分:6)

您可以创建以下中间类:

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

以及以下序列化程序:

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

然后在你的控制器中:

    both_layers = BothLayers.new(@layer1,@layer2)
    respond_with( both_layers, serializer: BothLayersSerializer )

答案 1 :(得分:1)

创建一个新哈希并将数组值传递给它。

respond_with({:LayerOne => @layer1.as_json(:only => [:name, :percentage]), :LayerTwo => @layer2.as_json(:only => [:name, :off_target_by])})

我得到了这个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
        }
    ]
}

希望它有所帮助:)

编辑2:

您可以创建一个数组序列化程序来传递变量:

class LayerArraySerializer < ActiveModel::ArraySerializer
  self.root = false
end

并在您看来:

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

答案 2 :(得分:1)

使用JBuilder DSL是解决问题的绝佳方法。

https://github.com/rails/jbuilder

您想要的JSON响应是作为视图实现的,使您可以完全控制它的呈现方式。

答案 3 :(得分:0)

Railcasts在AR Serializer上有一个很棒的视频+文字教程,我相信你会在那里找到答案

http://railscasts.com/episodes/409-active-model-serializers

相关问题