4

次のような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

これは、エスケープされた json データの 2 つの文字列を持つ json オブジェクトを返します!

deep_object_2_to_json 関数には、ネストされたインクルードのレイヤーが既にいくつかあるため、これらを 1 つの関数にリファクタリングする必要はありません。上記の二重エスケープの問題なしに、将来さらにオブジェクトを追加するためにこれを簡単に拡張できるようにする方法はありますか?

ご指摘ありがとうございます。

4

3 に答える 3

7

to_json簡単に呼び出すことができるものを作成する必要があるようです。

アクティブなレコード オブジェクトの明白な候補は ですas_json。これは、実際にオブジェクトを json に変換することを除いてto_json、(オプションなどを含めて) すべてのことを行います。:include代わりに、必要に応じて操作できる ruby​​ ハッシュを取得し、to_json を呼び出します。たとえば、次のことができます

render :json => {
  :o1 => object1.as_json(:include => :blah),
  :o2 => object2.as_json(:include => :blah)
}
于 2012-06-26T16:24:25.947 に答える
1

クラスをリファクタリングしてto_jsonメソッドを介してJSONを返すことができる場合は、2つ以上のオブジェクトを配列に貼り付けて、配列を呼び出すことができます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
于 2012-06-26T15:57:33.977 に答える
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 への参照を持つべきではありません。

于 2012-06-26T16:08:05.967 に答える