Perbedaan antara .build, .create, dan .create! dan kapan mereka harus digunakan?

167

Jadi saya telah melihat orang yang menggunakan .build, .createdan .create!dalam pengendali mereka lebih dan lebih akhir-akhir ini. Apa bedanya hanya menggunakan .newdan melewatkan objek param'd lalu .save? Apakah ada pro dan kontra? Apakah menggunakan metode-metode lain ini menawarkan manfaat?

Tim Knight
sumber

Jawaban:

234

Ada beberapa perbedaan, tetapi tidak terlalu besar:

  1. .createsetara dengan .newdiikuti oleh .save. Itu lebih ringkas.
  2. .create!sama dengan .newdiikuti oleh .save!(melempar kesalahan jika penyimpanan gagal). Ini juga hanya sedikit lebih pendek
  3. Saya pikir .buildadalah sebagian besar alias untuk .new. Ini bekerja satu cara di Rails 3 dan cara lain di Rails <3.x

Namun, bagian terpenting adalah bahwa metode ini dapat dipanggil melalui asosiasi ( has_many, dll.) Untuk secara otomatis menghubungkan kedua model.

zenazn
sumber
1
Saya memilih yang ini sebagai jawaban yang paling benar karena disebutkan tentang kemampuan untuk menghubungkan model terkait dengan mereka - itu adalah perbedaan yang menarik dan penting yang saya pikir lebih baik menggunakan .new dan .save. Yang butuh kerja ekstra. Terima kasih.
Tim Knight
11
Klarifikasi kecil pada 3 - build tidak lebih dari sekedar yang baru - itu juga menetapkan tautan asosiasi.
Two Bit Gangster
116
Build berbeda dari New. Tetapi perbedaannya bukan karena ia menetapkan tautan asosiasi (Baru juga melakukannya untuk instance baru). Perbedaannya adalah bahwa Build mengisi pemanggil dengan instance baru, tetapi New tidak. Jadi misalnya: Wall.posts.new memberi Anda posting baru yang terkait dengan Wall Anda, tetapi Wall.posts masih kosong setelah panggilan ini. Wall.posts.build memberi Anda pos baru yang terkait dengan Dinding Anda, dan Wall.post Anda sekarang memiliki satu pos di dalamnya.
Amin Ariana
3
Bukankah itu hanya alias sekarang, tanpa fungsi khusus?
Gabriele Cirulli
14
Di Rails 4, saya baru saja memeriksa konsol. wall.posts.new dan wall.posts.build sama-sama mengisi objek dinding dengan cara yang persis sama. Berarti setelah wall.posts.new, wall.posts tidak kosong seperti yang diklaim dalam komentar Amin.
Bot
35

Meskipun benar bahwa createpanggilan newdan kemudian saveada perbedaan besar antara dua alternatif dalam nilai pengembaliannya.

Savemengembalikan salah satu trueatau falsetergantung pada apakah objek berhasil disimpan ke database atau tidak. Ini kemudian dapat digunakan untuk kontrol aliran sesuai contoh pertama dalam pertanyaan di atas.

Createakan mengembalikan model terlepas dari apakah objek itu disimpan atau tidak. Ini memiliki implikasi untuk kode di atas bahwa cabang atas ifpernyataan akan selalu dieksekusi bahkan jika objek gagal validasi dan tidak disimpan.

Jika Anda menggunakan createdengan logika percabangan Anda berisiko gagal diam yang tidak terjadi jika Anda menggunakan new+ save.

create! tidak mengalami masalah yang sama seperti yang timbul dan pengecualian jika catatan tidak valid.

The createalternatif dapat berguna dalam controller di mana respond_withdigunakan untuk API (JSON / XML) tanggapan. Dalam hal ini keberadaan kesalahan pada objek akan menyebabkan kesalahan dikembalikan dalam respons dengan status unprocessable_entity, yang persis seperti yang Anda inginkan dari API.

Saya akan selalu menggunakan opsi new+ saveuntuk html, terutama jika Anda mengandalkan nilai balik untuk kontrol aliran.

nmott
sumber
6

#create adalah versi yang lebih baru dan simpan. #membuat! melempar pengecualian jika validasi tidak positif.

rkj
sumber
5

Saya akan menjawab kedua jawaban di atas. Plus untuk create, seseorang tidak dapat lulus falsesebagai argumen yang dapat Anda lakukan save. Melewati falsesebagai argumen akan melewati semua validasi rel

Vineeth Pradhan
sumber