我有一个控制器返回一个像这样的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函数已经有几层嵌套包含,所以我宁愿不必将它们重构为单个函数。有没有办法使这个可以轻松扩展,以便将来添加更多的对象,而不会出现上面的双重转义问题?
感谢您的任何指示。
答案 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有任何引用。