Jawaban:
Pada dasarnya destroy
menjalankan semua callback pada model sementara delete
tidak.
Dari API Rails :
ActiveRecord::Persistence.delete
Menghapus catatan dalam database dan membekukan instance ini untuk mencerminkan bahwa tidak ada perubahan yang harus dilakukan (karena tidak dapat dipertahankan). Mengembalikan contoh beku.
Baris hanya dihapus dengan pernyataan SQL DELETE pada kunci utama catatan, dan tidak ada panggilan balik yang dijalankan.
Untuk menegakkan callback sebelum_destroy dan after_destroy objek atau apa pun: opsi asosiasi yang bergantung, gunakan #destroy.
ActiveRecord::Persistence.destroy
Menghapus catatan dalam database dan membekukan instance ini untuk mencerminkan bahwa tidak ada perubahan yang harus dilakukan (karena tidak dapat dipertahankan).
Ada serangkaian panggilan balik yang terkait dengan penghancuran. Jika panggilan balik before_destroy kembali palsu tindakan dibatalkan dan menghancurkan kembali palsu. Lihat ActiveRecord :: Callbacks untuk detail lebih lanjut.
model#before_destroy
yang dapat digunakan untuk menghentikan destroy()
panggilan terakhir dalam kondisi tertentu.
delete
hanya akan menghapus catatan objek saat ini dari db tetapi tidak terkait dengan catatan anak-anak dari db.
destroy
akan menghapus catatan objek saat ini dari db dan juga catatan anak-anak terkait dari db.
Penggunaannya sangat penting:
Jika beberapa objek orang tua Anda membagikan objek anak-anak biasa, maka memanggil destroy
objek induk tertentu akan menghapus objek anak-anak yang dibagikan di antara banyak orang tua lainnya.
destroy
adalah keturunan , bukan anak - anak : menurut dokumentasi, menghancurkan "menciptakan objek baru dari atribut, dan kemudian memanggil menghancurkan di atasnya." rubydoc.info/docs/rails/4.1.7/ActiveRecord%2Felation:destroy
Ketika Anda memohon destroy
atau destroy_all
pada suatu ActiveRecord
objek, proses ActiveRecord
'penghancuran' dimulai, ia menganalisis kelas yang Anda hapus, itu menentukan apa yang harus dilakukan untuk dependensi, dijalankan melalui validasi, dll.
Ketika Anda memohon delete
atau delete_all
pada suatu objek, ActiveRecord
hanya mencoba menjalankan DELETE FROM tablename WHERE conditions
kueri terhadap db, tidak melakukan ActiveRecord
tugas tingkat- lain .
Ya ada perbedaan besar antara kedua metode. Gunakan delete_all jika Anda ingin catatan dihapus dengan cepat tanpa model panggilan balik dipanggil
Jika Anda peduli dengan model Anda, callback kemudian gunakan destroy_all
Dari dokumen resmi
http://apidock.com/rails/ActiveRecord/Base/destroy_all/class
destroy_all (kondisi = nil) publik
Hancurkan kondisi pencocokan catatan dengan membuat instance setiap catatan dan memanggil metode penghancurannya. Setiap panggilan balik objek dieksekusi (termasuk: opsi asosiasi dependen dan metode before_destroy / after_destroy Observer). Mengembalikan koleksi benda yang dihancurkan; masing-masing akan dibekukan, untuk mencerminkan bahwa tidak ada perubahan yang harus dilakukan (karena tidak dapat dipertahankan).
Catatan: Instansiasi, eksekusi panggilan balik, dan penghapusan setiap catatan bisa memakan waktu ketika Anda menghapus banyak catatan sekaligus. Ini menghasilkan setidaknya satu query SQL DELETE per record (atau mungkin lebih, untuk menegakkan callback Anda). Jika Anda ingin menghapus banyak baris dengan cepat, tanpa memperhatikan asosiasi atau panggilan baliknya, gunakan delete_all sebagai gantinya.
Pada dasarnya "delete" mengirimkan permintaan langsung ke database untuk menghapus catatan. Dalam hal itu Rails tidak tahu atribut apa yang ada dalam catatan itu dihapus atau apakah ada panggilan balik (seperti before_destroy
).
Metode "hancurkan" mengambil id yang lewat, mengambil model dari database menggunakan metode "temukan", kemudian panggilan hancurkan pada itu. Ini berarti callback terpicu.
Anda ingin menggunakan "hapus" jika Anda tidak ingin callback terpicu atau Anda menginginkan kinerja yang lebih baik. Kalau tidak (dan sebagian besar waktu) Anda akan ingin menggunakan "menghancurkan".
Sudah banyak jawaban; ingin melompat dengan sedikit lebih banyak.
dokumen :
Untuk has_many, hancurkan dan hancurkan_all akan selalu memanggil metode hancurkan dari catatan yang dihapus sehingga callback dijalankan. Namun delete dan delete_all akan melakukan penghapusan sesuai dengan strategi yang ditentukan oleh opsi: dependen, atau jika tidak ada: dependen diberikan, maka ia akan mengikuti strategi default. Strategi default adalah tidak melakukan apa-apa (biarkan kunci asing dengan set induk ids ditetapkan), kecuali untuk has_many: through, di mana strategi default adalah delete_all (hapus catatan bergabung, tanpa menjalankan callback mereka).
The delete
verbage bekerja secara berbeda untuk ActiveRecord::Association.has_many
dan ActiveRecord::Base
. Untuk yang terakhir, hapus akan mengeksekusi SQL DELETE
dan memotong semua validasi / panggilan balik. Yang pertama akan dieksekusi berdasarkan :dependent
opsi yang diteruskan ke asosiasi. Namun, selama pengujian, saya menemukan efek samping berikut di mana callback hanya dijalankan untuk delete
dan tidakdelete_all
dependent: :destroy
Contoh:
class Parent < ApplicationRecord
has_many :children,
before_remove: -> (_) { puts "before_remove callback" },
dependent: :destroy
end
class Child < ApplicationRecord
belongs_to :parent
before_destroy -> { puts "before_destroy callback" }
end
> child.delete # Ran without callbacks
Child Destroy (99.6ms) DELETE FROM "children" WHERE "children"."id" = $1 [["id", 21]]
> parent.children.delete(other_child) # Ran with callbacks
before_remove callback
before_destroy callback
Child Destroy (0.4ms) DELETE FROM "children" WHERE "children"."id" = $1 [["id", 22]]
> parent.children.delete_all # Ran without callbacks
Child Destroy (1.0ms) DELETE FROM "children" WHERE "children"."parent_id" = $1 [["parent_id", 1]]