この問題は適切に調査されていません。実際の問題は_render :json
_内にあります。
元の質問の最初のコードを貼り付けると、期待どおりの結果が得られます。ただし、まだ注意が必要です。この例を参照してください。
_render :json => current_user
_
is[〜#〜] not [〜#〜]と同じ
_render :json => current_user.to_json
_
つまり、_render :json
_は、Userオブジェクトに関連付けられた_to_json
_メソッドを自動的に呼び出しません。 実際に、User
モデルで_to_json
_がオーバーライドされている場合、_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
_
これはすべて私には馬鹿げているようです。これは、タイプ_Model#to_json
_が指定されているときに、render
が実際に_:json
_を呼び出していないことを教えているようです。誰かがここで実際に何が起こっているのか説明できますか?
これで私を助けることができるgeniiは、おそらく他の質問に答えることができます: 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
_
何か案は?
_to_json
_は1つのパラメーター、options
ハッシュでオーバーライドする必要があるため、ArgumentError: wrong number of arguments (1 for 0)
を取得しています。
_def to_json(options)
...
end
_
_to_json
_、_as_json
_、およびレンダリングの詳細説明:
ActiveSupport 2.3.3では、遭遇したような問題に対処するために_as_json
_が追加されました。 jsonのcreationは、jsonのrenderingとは別にする必要があります。
これで、オブジェクトで_to_json
_が呼び出されるたびに、_as_json
_が呼び出されてデータ構造が作成され、そのハッシュが_ActiveSupport::json.encode
_を使用してJSON文字列としてエンコードされます。これは、オブジェクト、数値、日付、文字列など、すべてのタイプで発生します(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
_オーバーライドで適切に表される(または表されない)限り、1つのモデルを表示するコントローラーコードは次のようになります。
_format.json { render :json => @user }
_
ストーリーの教訓は次のとおりです:_to_json
_を直接呼び出すのを避け、render
があなたのためにそれを行うことを許可します。 JSON出力を調整する必要がある場合は、_as_json
_。を呼び出します
_format.json { render :json =>
@user.as_json(:only => [:username], :methods => [:avatar]) }
_
Rails 3でこれに問題がある場合、serializable_hash
の代わりに as_json
。これにより、XMLフォーマットも無料で取得できます。
これは私が永遠に理解するのにかかりました。それが誰かを助けることを願っています。
ユーザーのオプションを無視したくないが、ユーザーのオプションも追加したい場合:
def as_json(options)
# this example DOES NOT ignore the user's options
super({:only => [:email, :handle]}.merge(options))
end
これが誰にも役立つことを願っています:)
To_jsonではなく、as_jsonをオーバーライドします。そして、as_jsonから必要なものを呼び出します。
これを試して:
def as_json
{ :username => username, :foo => foo, :bar => bar }
end