11

Rails 3.1 のアプリケーションから「type」属性を含むオブジェクトを JSON として返す場合、「type」属性が含まれていないようです。次のものがあるとします。

STIテーブルアニマル対応モデル。Animal を継承した Cat、Dog、Fish のモデル。

JSON 経由で動物を返す場合、「タイプ」列を含めたいのですが、これは行われません。

jQuery.ajax("http://localhost:3001/animals/1", {dataType: "json"});

収量:

responseText: "{"can_swim":false,"created_at":"2012-01-20T17:55:16Z","id":1,"name":"Fluffy","updated_at":"2012-01-20T17:55:16Z","weight":9.0}"

これはto_jsonの問題のようです:

bash-3.2$ rails runner 'p Animal.first.to_yaml'
"--- !ruby/object:Cat\nattributes:\n  id: 1\n  type: Cat\n  weight: 9.0\n  name: Fluffy\n  can_swim: false\n  created_at: 2012-01-20 17:55:16.090646000 Z\n  updated_at: 2012-01-20 17:55:16.090646000 Z\n"

bash-3.2$ rails runner 'p Animal.first.to_json'
"{\"can_swim\":false,\"created_at\":\"2012-01-20T17:55:16Z\",\"id\":1,\"name\":\"Fluffy\",\"updated_at\":\"2012-01-20T17:55:16Z\",\"weight\":9.0}"

この動作の背後にある理由と、それをオーバーライドする方法を知っている人はいますか?

4

4 に答える 4

19

これが私がしたことです。不足typeしているものを結果セットに追加するだけです

  def as_json(options={})
    super(options.merge({:methods => :type}))
  end
于 2013-09-26T15:56:25.747 に答える
6

as_jsonメソッドをオーバーライドします。to_json出力を生成するために使用されます。次のようなことができます:

def as_json options={}
 {
   id: id,
   can_swim: can_swim,
   type: type
 }
end
于 2012-01-20T18:07:00.790 に答える
1

私にとって、Rails 2.3.12 では、上記は機能しません。

私は(もちろん私のモデルで)次のようなことができます:

class Registration < ActiveRecord::Base

  def as_json(options={})
    super(options.merge(:include => [:type]))
  end

end

しかし、それにより to_json は次のようなエラーをスローします:

NoMethodError: undefined method `serializable_hash' for "Registration":String

これでこれを回避しました。これは、このメソッドをエクスポートしたいオブジェクトに打ち込みます

class Registration < ActiveRecord::Base

  def as_json(options={})
    super(options.merge(:include => [:type]))
  end

  def type
    r  = self.attributes["type"]
    def r.serializable_hash(arg)
      self
    end
    r
  end
end

私のアプリでは、これをミックスインに入れました:

module RailsStiModel
  # The following two methods add the "type" parameter to the to_json output.
  # see also:
  # http://stackoverflow.com/questions/8945846/including-type-attribute-in-json-respond-with-rails-3-1/15293715#15293715
  def as_json(options={})
    super(options.merge(:include => [:type]))
  end

  def type
    r  = self.attributes["type"]
    def r.serializable_hash(arg)
      self
    end
    r
  end
end

そして今、私のモデルクラスに以下を追加します:

include RailsStiModel
于 2013-03-08T12:10:20.877 に答える