Di Rails, bagaimana Anda membuat JSON menggunakan tampilan?

125

Misalkan Anda berada di pengontrol pengguna Anda dan Anda ingin mendapatkan respons json untuk permintaan acara, alangkah baiknya jika Anda dapat membuat file dalam tampilan / pengguna / direktori Anda, bernama show.json dan setelah pengguna Anda # tampilkan tindakan selesai, itu membuat file.

Saat ini Anda perlu melakukan sesuatu seperti:

def show
  @user = User.find( params[:id] )
  respond_to do |format|
    format.html
    format.json{
      render :json => @user.to_json
    }
  end
end

Tapi alangkah baiknya jika Anda bisa membuat file show.json yang secara otomatis di-render seperti:

def show
  @user = User.find( params[:id] )
  respond_to do |format|
    format.html
    format.json
  end
end

Ini akan menyelamatkan saya dari banyak kesedihan, dan akan menghilangkan perasaan kotor yang mengerikan yang saya dapatkan ketika saya memberikan json saya di controller.

Matius
sumber
Melihat posting ini sekarang, sepertinya ini tidak akan menyelamatkan saya banyak, tetapi saya memiliki kasus yang lebih rumit, percayalah ketika saya mengatakan ini menyebabkan saya sakit kepala
Matius
1
Di Rails 3, Anda bisa menelepon format.jsondengan show.json.erbfile. Lihat jawaban saya.
James Lim

Jawaban:

64

Anda harus dapat melakukan sesuatu seperti ini di respond_toblok Anda :

respond_to do |format|
    format.json 
    render :partial => "users/show.json"
end

yang akan merender template di app/views/users/_show.json.erb.

Alex Reisner
sumber
5
Ini bagus, tetapi Anda akan segera menemukan erb adalah cara yang menyakitkan untuk menghasilkan json. Lihatlah jawaban saya untuk beberapa alternatif.
tybro0103
1
Apakah ada cara untuk melakukannya tanpa menggunakan parsial?
Wylliam Judd
55

Coba tambahkan tampilan. users/show.json.erbIni harus di-render ketika Anda membuat permintaan untuk format JSON, dan Anda mendapatkan manfaat tambahan dari itu dirender oleh erb juga, sehingga file Anda bisa terlihat seperti ini

{
    "first_name": "<%= @user.first_name.to_json %>",
    "last_name": "<%= @user.last_name.to_json %>"
}
erik
sumber
9
Anda mungkin ingin menggunakannya @user.first_name.to_jsonsebagai gantinya escape_javascript. Ada beberapa perbedaan halus antara apa yang diizinkan JS dan apa yang benar - benar JSON. (Dan perbedaan-perbedaan itu menjadi penting ketika browser mengimplementasikan parser JSON mereka sendiri.)
James A. Rosen
1
Anda mungkin harus mengubah tanda kutip tunggal menjadi tanda kutip ganda, karena JSON (tidak seperti JS) hanya menerima string kutipan ganda.
Abe Voelker
1
Ini bagus, tetapi Anda akan segera menemukan erb adalah cara yang menyakitkan untuk menghasilkan json. Lihatlah jawaban saya untuk beberapa alternatif.
tybro0103
Saya tahu ini adalah jawaban lama, tetapi itu sepenuhnya salah. to_json akan mengembalikan string json yang telah diformat, "" sehingga json yang dihasilkan tidak akan pernah valid dengan tanda kutip tambahan ("" value ""). Juga, jika nama depan pengguna adalah nihil, json yang dihasilkan akan memiliki string "null" sebagai nilainya. Juga <% = menggunakan html melarikan diri yang akan memotong-motong karakter html dalam data input.
d4n3
Saya pikir Anda juga perlu menghapus tanda kutip di sekitar <%= xyz.to_json %>jika tidak, Anda akan memiliki tanda kutip tambahan.
akostadinov
32

Seperti yang disebutkan orang lain, Anda memerlukan tampilan pengguna / show.json, tetapi ada opsi untuk dipertimbangkan untuk bahasa templating ...

ERB

Bekerja di luar kotak. Bagus untuk HTML, tetapi Anda akan dengan cepat merasakannya buruk untuk JSON.

RABL

Solusi yang bagus Harus menambahkan ketergantungan dan mempelajari DSL-nya.

JSON Builder

Kesepakatan yang sama dengan RABL: Solusi yang bagus. Harus menambahkan ketergantungan dan mempelajari DSL-nya.

Ruby Biasa

Ruby luar biasa dalam menghasilkan JSON dan tidak ada yang baru untuk dipelajari karena Anda dapat memanggil objek to_jsonHash atau AR. Cukup daftarkan ekstensi .rb untuk templat (dalam inisialisasi):

ActionView::Template.register_template_handler(:rb, :source.to_proc)

Kemudian buat tampilan pengguna / show.json.rb:

@user.to_json

Untuk info lebih lanjut tentang pendekatan ini lihat http://railscasts.com/episodes/379-template-handlers

tybro0103
sumber
7
Perhatikan bahwa pada rails 4, pengendali template .ruby terdaftar secara default github.com/rails/rails/commit/de1060f4e02925c12004f2 sehingga Anda dapat melewatkan mendaftar .rb dan beri nama pengguna file Anda / show.json.ruby.
Tim Diggins
1
Selain itu, untuk memperbarui ini lebih lanjut, json_builder telah digantikan oleh github.com/rails/jbuilder .
Tim Diggins
27

RABL mungkin solusi terbaik untuk ini yang pernah saya lihat jika Anda mencari alternatif yang lebih bersih untuk sintaks ERb. json_builder dan argonaut, yang merupakan solusi lain, keduanya tampak agak ketinggalan jaman dan tidak akan berfungsi dengan Rails 3.1 tanpa perbaikan.

RABL tersedia melalui permata atau lihat repositori GitHub; contoh yang bagus juga

https://github.com/nesquena/rabl

zapnap
sumber
21

Sekedar memperbarui jawaban ini demi orang lain yang kebetulan berakhir di halaman ini.

Di Rails 3, Anda hanya perlu membuat file di views/users/show.json.erb. The @userobjek akan tersedia untuk tampilan (seperti itu akan untuk html.) Anda bahkan tidak perlu to_jsonlagi.

Untuk meringkas, hanya saja

# users contoller
def show
  @user = User.find( params[:id] )
  respond_to do |format|
    format.html
    format.json
  end
end

dan

/* views/users/show.json.erb */
{
    "name" : "<%= @user.name %>"
}
James Lim
sumber
1
Saya menjawab ini 1,5 tahun yang lalu. Saat ini saya hanya menggunakan response_with kapan pun saya membutuhkan JSON misalnya respond_with @user, only: [:name]. Lihat tutorial ini untuk informasi lebih lanjut.
James Lim
1
Hanya untuk menambah jawaban ini, ini sebenarnya berbahaya karena dua alasan: ini memungkinkan injeksi dari data pengguna karena tidak luput dari garis baru dan garis miring terbalik, dan juga <% = html lolos dari data sehingga mis. Sean O'Connor akan memiliki namanya hancur ke Sean O & apos; Connor.
d4n3
10

Cukup tambahkan show.json.erbfile dengan konten

<%= @user.to_json %>

Kadang-kadang berguna ketika Anda memerlukan beberapa metode pembantu tambahan yang tidak tersedia di controller, yaitu image_path(@user.avatar)atau sesuatu untuk menghasilkan properti tambahan di JSON:

<%= @user.attributes.merge(:avatar => image_path(@user.avatar)).to_json %>
Priit
sumber
8
Itu harus <%= raw(@user.to_json) %>untuk menghindari melarikan diri HTML. Apa yang saya lakukan adalah bahwa saya mengandalkan to_json selama itu memberi saya apa yang saya inginkan, tetapi ketika saya ingin melakukan sesuatu yang lain saya templat dengan apa yang biasanya a { :blah => @user.the_blah }.to_json.
clacke
0

Saya baru mengenal RoR inilah yang saya temukan. Anda dapat langsung membuat format json

def YOUR_METHOD_HERE
  users = User.all
  render json: {allUsers: users} # ! rendering all users
END
aRtoo
sumber