1. ホーム
  2. ruby-on-rails

[解決済み] Railsでto_jsonをオーバーライドするには?

2023-02-05 23:24:55

質問


更新しました。

この問題は適切に調査されていませんでした。本当の問題は render :json .

元の質問にある最初のコードの貼り付けは、期待通りの結果を得ることができます。しかし、まだ注意点があります。この例をご覧ください。

render :json => current_user

ではない と同じです。

render :json => current_user.to_json

ということです。 render :json は自動的に to_json メソッドを自動的に呼び出すことはありません。 実際には であれば、もし to_json がオーバーライドされている場合 User モデルで render :json => @user が生成するのは ArgumentError が生成されます。

概要

# works if User#to_json is not overridden
render :json => current_user

# If User#to_json is overridden, User requires explicit call
render :json => current_user.to_json

これはすべて、私には馬鹿げているように思えます。これは、私にこう言っているように思えます。 render は実際には Model#to_json と入力すると :json が指定されています。どなたか、何が本当に起こっているのか説明していただけませんか?

これで私を助けることができるどんな天才も、おそらく私の他の質問に答えることができます。 Railsで@foo.to_json(options)と@bars.to_json(options)を組み合わせてJSON応答を構築する方法。


オリジナルの質問です。

私はSOでいくつかの他の例を見てきましたが、私はどれも私が探しているものを行うことはありません。

私は試しています。

class User < ActiveRecord::Base

  # this actually works! (see update summary above)
  def to_json
    super(:only => :username, :methods => [:foo, :bar])
  end

end

私は ArgumentError: wrong number of arguments (1 for 0)

/usr/lib/ruby/gems/1.9.1/gems/activesupport-2.3.5/lib/active_support/json/encoders/object.rb:4:in `to_json

何かアイデアはありますか?

どのように解決するのですか?

あなたは ArgumentError: wrong number of arguments (1 for 0) なぜなら to_json は1つのパラメータでオーバーライドする必要があるからです。 options ハッシュです。

def to_json(options)
  ...
end


の長い説明 to_json , as_json とか、レンダリングとか。

ActiveSupport 2.3.3 では。 as_json が追加され、あなたが遭遇したような問題に対処できるようになりました。その 作成 とは別に json を作成する必要があります。 レンダリング とは別のものでなければなりません。

さて、いつでも to_json がオブジェクト上で呼び出されると as_json が呼び出されてデータ構造が作成され、そのハッシュがJSON文字列として ActiveSupport::json.encode . これは、オブジェクト、数値、日付、文字列など、すべての型に対して行われます(ActiveSupportのコードを参照してください)。

ActiveRecordオブジェクトも同じように動作します。デフォルトの as_json の実装があり、これはモデルのすべての属性を含むハッシュを作成します。 をオーバーライドする必要があります。 as_json をオーバーライドして、必要なJSON構造を作成する必要があります。 . as_json のように、古い to_json のように、宣言的にインクルードする属性やメソッドを指定するためのオプション・ハッシュを取ります。

def as_json(options)
  # this example ignores the user's options
  super(:only => [:email, :handle])
end

コントローラーに render :json => o は文字列かオブジェクトを受け取ることができます。 文字列であればレスポンスボディとして渡され、オブジェクトであれば to_json が呼び出され、それがきっかけで as_json をトリガーします。

ですから、あなたのモデルが適切に as_json で適切に表現されている限り、一つのモデルを表示するためのコントローラのコードは次のようになります。

format.json { render :json => @user }

この話のモラルは 電話をかけないようにする to_json を直接呼び出すのは避けましょう。 render を実行するようにします。JSONの出力に手を加える必要がある場合は as_json .

format.json { render :json => 
    @user.as_json(:only => [:username], :methods => [:avatar]) }