如何一次返回2个json对象?

时间:2012-06-26 15:50:21

标签: ruby-on-rails ruby-on-rails-3 json rest

我有一个控制器返回一个像这样的json结构:

def show
  # .......
  o_json = deep_object_1_to_json(o)
  render :json => o_json
end

private
def deep_object_1_to_json(o)
  o.to_json(
    :include => {....})
end

现在我需要扩展它以返回2个对象。然而,显而易见的解决方案是给我带来问题:

def show
  # .......
  o1_json = deep_object_1_to_json(o)
  o2_json = deep_object_2_to_json(o)
  render :json => 
  {
         :object_1 => o1_json,
         :object_2 => o2_json
  }
end

这将返回一个带有2个转义的json数据字符串的json对象!

deep_object_2_to_json函数已经有几层嵌套包含,所以我宁愿不必将它们重构为单个函数。有没有办法使这个可以轻松扩展,以便将来添加更多的对象,而不会出现上面的双重转义问题?

感谢您的任何指示。

3 个答案:

答案 0 :(得分:7)

听起来你应该构建一些可以轻松调用to_json的东西。

活跃记录对象的明显候选者是as_json。除了实际将对象转换为json之外,它执行to_json所做的所有事情(包括:include选项等)。相反,你得到一个红宝石哈希,你可以根据需要操作,然后调用to_json。例如,你可以做

render :json => {
  :o1 => object1.as_json(:include => :blah),
  :o2 => object2.as_json(:include => :blah)
}

答案 1 :(得分:1)

如果你可以通过to_json方法重构你的类来返回它的JSON,你可以简单地将两个或多个对象放到一个数组中并在数组上调用to_json

1.9.3-p125 :001 > require 'json'
 => true 
1.9.3-p125 :002 > [{foo: "bar"}, {bar: "foo"}].to_json
 => "[{\"foo\":\"bar\"},{\"bar\":\"foo\"}]" 

示例:

def to_json
  super(include: [:some_association])
end

答案 2 :(得分:1)

您的控制器不应该将对象序列化为JSON,直到将其移交给渲染之前。

换句话说,deep_object_1_to_json应该只是deep_object_1。然后,您可以将返回值打包到数组或散列中,并将其呈现为JSON。

def show
  # .......
  o1 = deep_object_1(o)
  o2 = deep_object_2(o)
  render :json =>
  {
         :object_1 => o1,
         :object_2 => o2
  }
end

现在改变它可能会很痛苦,但对于系统的未来,你真的应该这样做。 JSON只是一种通过线路或磁盘发送对象的格式;

,除非将代码传递给JSON,否则你的代码都不应该对JSON有任何引用。