maeshimaの日記

メモ書きです

ActiveRecord::Serialization#to_json(options = {})

rails2.3.4のドキュメントを読んだメモです。

モデルの名前をJSONのルートに含む

ActiveRecord::Base.include_root_in_jsonをtrueにすると、モデルの名前がJSONのルートに含まれるようになる。

konata = User.find(1)
ActiveRecord::Base.include_root_in_json = true
konata.to_json
# => { "user": {"id": 1, "name": "Konata Izumi", "age": 16,
                "created_at": "2006/08/01", "awesome": true} }
 ActiveRecord::Base.include_root_in_json = false
konata.to_json
# => {"id": 1, "name": "Konata Izumi", "age": 16,
      "created_at": "2006/08/01", "awesome": true}

デフォルトは、いつの間にかできてたinitializers/new_rails_defaults.rbでtrueにセットされてる。

出力するattributesの制御

  • optionなしだとすべてのmodelのattributesが含まれたjsonが返される
  • :onlyと:exceptでattributesの制限ができる
  • :methodsでメソッドの結果をjsonに含めることができる
  • :includeで関連モデルも含めることができる
  • 関連のネストもできる

関連のネストの例

  konata.to_json(:include => { :posts => {
                                 :include => { :comments => {
                                               :only => :body } },
                                 :only => :title } })
  # => {"id": 1, "name": "Konata Izumi", "age": 16,
        "created_at": "2006/08/01", "awesome": true,
        "posts": [{"comments": [{"body": "1st post!"}, {"body": "Second!"}],
                   "title": "Welcome to the weblog"},
                  {"comments": [{"body": "Don't think too hard"}],
                   "title": "So I was thinking"}]}

実際に使ってみて

なんかas_jsonが従来のto_jsonの働きをするようになったような気がする。to_jsonを使うと

Account.first.to_json
# => "{\"json_class\":\"Account\",\"attributes_cache\":{},\"attributes\": 
        # hogehoge
      }}"

のように、ActiveRecord::Base.include_root_in_jsonの値にかかわらずjson_classとattributes_cacheとかいうのが自動でつく。
as_jsonはドキュメントのto_jsonと同じ挙動。このへんはドキュメントがまだおいついてないのかなー。

2.3.3からこのような挙動になったのだと思うけど、ググっても詳細な情報はでてこなかった。だれか詳細ご存じの方いらっしゃったら教えてください><

Rails2.3.3での変更点 - おもしろWEBサービス開発日記

追記

ドキュメントのActiveSupport::TimeWithZone#as_jsonなどのExampleがto_jsonになってて何が正しいのかよくわかんない状況。