【问题标题】:How to return 2 json objects at once?如何一次返回 2 个 json 对象?
【发布时间】:2012-06-26 15:50:21
【问题描述】:

我有一个控制器返回一个像这样的 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 函数已经有多层嵌套包含,所以我宁愿不必将它们重构为单个函数。有没有办法使它易于扩展以在将来添加更多对象而不会出现上述双重转义问题?

感谢您的任何指点。

【问题讨论】:

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


    【解决方案1】:

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

    活动记录对象的明显候选对象是as_json。这会完成 to_json 所做的所有事情(包括 :include 选项等),但实际上将对象转换为 json。相反,您会得到一个 ruby​​ 哈希,您可以根据需要对其进行操作,然后调用 to_json。例如你可以这样做

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

    【讨论】:

    • 酷,不知道 as_json。看起来我的 deep_objects_to_json 方法可以更改为 deep_objects_as_json ,然后我可以按照 benzando 的建议在渲染时调用 to_json 一次。谢谢!
    • 很好,我忘了as_json。好多了。
    【解决方案2】:

    您的控制器不应该将对象序列化为 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 的引用,除非它传递它以进行渲染。

    【讨论】:

    • 好的,这是有道理的,你知道获得活动记录对象的内存版本的最佳方法是什么,该对象将在调用 to_json 时呈现所有必需的嵌套关联?
    【解决方案3】:

    如果您可以重构您的类以通过 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
    

    【讨论】:

    • 我不确定这是可能的。如果我的对象“foo”是一个活动记录对象,它有很多“条”,每个条都有一个“baz”等。我希望这些都被序列化,那么我必须用必要的方法独立调用 to_json包括。
    • 您可以在 to_json 实现中调用包含。我添加了一个示例。
    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    • 2013-05-02
    相关资源
    最近更新 更多