Memperbarui:
Masalah ini tidak dieksplorasi dengan benar. Masalah sebenarnya ada di dalam render :json
.
Tempel kode pertama dalam pertanyaan asli akan menghasilkan hasil yang diharapkan. Namun, masih ada keberatan. Lihat contoh ini:
render :json => current_user
adalah TIDAK sama dengan
render :json => current_user.to_json
Artinya, render :json
tidak akan secara otomatis memanggil to_json
metode yang terkait dengan objek Pengguna. Faktanya , jika model to_json
diganti User
, render :json => @user
akan menghasilkan seperti yang ArgumentError
dijelaskan di bawah ini.
ringkasan
# 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
Ini semua tampak konyol bagiku. Ini sepertinya memberi tahu saya bahwa render
sebenarnya tidak memanggil Model#to_json
ketika tipe :json
ditentukan. Adakah yang bisa menjelaskan apa yang sebenarnya terjadi di sini?
Setiap genii yang dapat membantu saya dengan ini kemungkinan dapat menjawab pertanyaan saya yang lain: Bagaimana membangun respons JSON dengan menggabungkan @ foo.to_json (opsi) dan @ bars.to_json (opsi) di Rails
Pertanyaan Asli:
Saya telah melihat beberapa contoh lain di SO, tetapi saya tidak melakukan apa yang saya cari.
Saya mencoba:
class User < ActiveRecord::Base
# this actually works! (see update summary above)
def to_json
super(:only => :username, :methods => [:foo, :bar])
end
end
Aku mulai ArgumentError: wrong number of arguments (1 for 0)
di
/usr/lib/ruby/gems/1.9.1/gems/activesupport-2.3.5/lib/active_support/json/encoders/object.rb:4:in `to_json
Ada ide?
sumber
username
,foo
ataubar
mengharapkan argumen?username
ini bukan metode danfoo
danbar
tidak memerlukan metode. Saya memperbarui pertanyaan saya untuk menunjukkan di mana kesalahan itu terjadi.Jawaban:
Anda mendapatkan
ArgumentError: wrong number of arguments (1 for 0)
karenato_json
perlu diganti dengan satu parameter,options
hash.Penjelasan lebih lama dari
to_json
,as_json
, dan rendering:Di ActiveSupport 2.3.3,
as_json
ditambahkan untuk mengatasi masalah seperti yang Anda temui. The penciptaan dari json harus terpisah dari render dari json tersebut.Sekarang, kapan saja
to_json
dipanggil pada suatu objek,as_json
dipanggil untuk membuat struktur data, dan hash itu dikodekan sebagai string JSON menggunakanActiveSupport::json.encode
. Ini terjadi untuk semua jenis: objek, numerik, tanggal, string, dll (lihat kode ActiveSupport).Objek ActiveRecord berperilaku dengan cara yang sama. Ada
as_json
implementasi default yang membuat hash yang menyertakan semua atribut model. Anda harus menggantias_json
Model Anda untuk membuat struktur JSON yang Anda inginkan .as_json
, seperti yang lamato_json
, mengambil opsi hash di mana Anda dapat menentukan atribut dan metode untuk disertakan secara deklaratif.Di pengontrol Anda,
render :json => o
dapat menerima string atau objek. Jika itu sebuah string, itu dilewatkan sebagai tubuh respons, jika itu sebuah objek,to_json
disebut, yang memicuas_json
seperti dijelaskan di atas.Jadi, selama model Anda diwakili dengan benar dengan
as_json
penggantian (atau tidak), kode pengontrol Anda untuk menampilkan satu model akan terlihat seperti ini:Moral dari cerita ini adalah: Hindari menelepon
to_json
secara langsung, izinkanrender
untuk melakukan itu untuk Anda. Jika Anda perlu mengubah keluaran JSON, panggilas_json
.sumber
as_json
. Seperti yang Anda lihat di dokumen ActiveRecord :: Serialization ( api.rubyonrails.org/classes/ActiveRecord/… ), hanya ada sedikit (tidak) dokumentasi untuk ini. Saya akan mencobanya :)as_json
dokumennya! Terima kasih lagi :)Jika Anda mengalami masalah dengan ini di Rails 3,
serializable_hash
gantias_json
. Ini akan mendapatkan format XML Anda secara gratis juga :)Aku butuh waktu lama untuk memikirkannya. Harapan yang membantu seseorang.
sumber
serializable_hash
? Ketika saya menggunakannya, itu mengubah keluaran xml saya berikutnya dari membungkus objek dengan namanya (misalnya "kutipan" untuk objek kutipan ") menjadi sebagai gantinya selalu membungkusnya dengan" <hash> ".to_xml
Untuk orang yang tidak ingin mengabaikan opsi pengguna tetapi juga menambahkan opsi mereka:
Semoga ini bisa membantu siapa saja :)
sumber
options
hash secara default= {}
sehingga tidak diperlukan saat meneleponTimpa bukan to_json, tapi as_json. Dan dari as_json panggil apa yang Anda inginkan:
Coba ini:
sumber
as_json
hanya untuk ActiveResource?render :json => current_user
saya mendapatkan hasil default yang diharapkan (semua atribut untukUser
model dalam format JSON). Ketika saya menambahkanas_json
metode keUser
model saya dan mencoba hal yang sama, saya mendapatkan kesalahan :(