Yanıtlar:
Temelde destroy
, modelde geri çağrıları çalıştırmaz, ancak delete
çalışmaz.
Gönderen Raylar API :
ActiveRecord::Persistence.delete
Veritabanındaki kaydı siler ve hiçbir değişiklik yapılmaması gerektiğini (kalıcı olamayacağı için) bu örneği dondurur. Dondurulmuş örneği döndürür.
Satır, kaydın birincil anahtarındaki SQL DELETE deyimiyle kaldırılır ve geri arama yapılmaz.
Nesnenin before_destroy ve after_destroy geri çağrılarını veya herhangi bir: bağımlı ilişkilendirme seçeneğini zorlamak için #destroy kullanın.
ActiveRecord::Persistence.destroy
Veritabanındaki kaydı siler ve hiçbir değişiklik yapılmaması gerektiğini (kalıcı olamayacağı için) bu örneği dondurur.
Destroy ile ilişkili bir dizi geri arama var. Before_destroy geri dönüşü false değerini döndürürse, eylem iptal edilir ve imha yanlış değerini döndürür. Daha fazla bilgi için ActiveRecord :: Geri Aramalara bakınız.
model#before_destroy
son destroy()
çağrıyı durdurmak için kullanılabilir .
delete
yalnızca geçerli nesne kaydını db'den siler, ancak ilişkili alt kayıtlarını db'den silmez.
destroy
geçerli nesne kaydını db'den ve ilişkili çocuk kaydını db'den siler.
Kullanımları gerçekten önemlidir:
Birden çok üst nesneniz ortak alt nesneleri paylaşıyorsa destroy
, belirli üst nesneyi çağırmak , diğer birden çok üst öğe arasında paylaşılan alt nesneleri siler.
destroy
olduğu soyundan değil, çocuklar : dokümantasyon, imha göre "nitelikler gelen yeni bir nesne oluşturur ve daha sonra aramaları üzerine yok eder." rubydoc.info/docs/rails/4.1.7/ActiveRecord%2FRelation:destroy
Bir nesneyi çağırdığınızda destroy
veya destroy_all
bir ActiveRecord
nesnede ActiveRecord
başlattığınızda, 'imha' işlemi başlatılır, sildiğiniz sınıfı analiz eder, bağımlılıklar için ne yapması gerektiğini belirler, doğrulamalarla çalışır vb.
Bir nesneyi çağırdığınızda delete
ya delete_all
da bir nesne üzerinde ActiveRecord
çalıştırdığınızda , yalnızca db'ye DELETE FROM tablename WHERE conditions
karşı sorguyu çalıştırmaya çalışır ve başka ActiveRecord
düzeyli görevler gerçekleştirmez.
Evet, iki yöntem arasında büyük bir fark vardır Kayıtların model geri çağrıları çağrılmadan hızla silinmesini istiyorsanız delete_all komutunu kullanın
Modellerinizin geri çağrılarını önemsiyorsanız destroy_all kullanın
Resmi dokümanlardan
http://apidock.com/rails/ActiveRecord/Base/destroy_all/class
destroy_all (koşullar = nil) herkese açık
Her kaydı somutlaştırarak ve destroy yöntemini çağırarak kayıt eşleştirme koşullarını imha eder. Her nesnenin geri çağrıları yürütülür (aşağıdakilere bağlıdır: bağımlı ilişkilendirme seçenekleri ve before_destroy / after_destroy Observer yöntemleri). Yok edilen nesnelerin koleksiyonunu döndürür; her biri, hiçbir değişiklik yapılmaması gerektiğini (kalıcı olamayacakları için) dondurmak için dondurulur.
Not: Birden fazla kaydı bir defada kaldırırken örnekleme, geri arama yürütme ve her kaydın silinmesi zaman alabilir. Kayıt başına en az bir SQL DELETE sorgusu oluşturur (veya geri aramalarınızı zorlamak için muhtemelen daha fazla). Dernekleri veya geri çağrıları için endişe etmeden birçok satırı hızlı bir şekilde silmek istiyorsanız, bunun yerine delete_all öğesini kullanın.
Temel olarak "sil" kaydı silmek için doğrudan veritabanına bir sorgu gönderir. Bu durumda Rails, kayıtta hangi niteliklerin silindiğini veya geri arama (örneğin before_destroy
) olup olmadığını bilmez .
"Destroy" yöntemi iletilen kimliği alır, "find" yöntemini kullanarak modeli veritabanından alır ve ardından destroy'i çağırır. Bu, geri aramaların tetiklendiği anlamına gelir.
Geri aramaların tetiklenmesini istemiyorsanız veya daha iyi bir performans istiyorsanız "sil" seçeneğini kullanmak istersiniz. Aksi takdirde (ve çoğu zaman) "yok et" i kullanmak istersiniz.
Şimdiden birçok cevap; biraz daha fazla atlamak istedim.
Has_many için destroy ve destroy_all her zaman kaldırılan kayıtların yok etme yöntemini çağırır, böylece geri çağrılar çalıştırılır. Ancak delete ve delete_all, silme işlemini: bağımlı seçenek tarafından belirtilen stratejiye göre yapar veya hayır: bağımlı seçenek belirtilmezse, varsayılan stratejiyi izler. Varsayılan strateji, has_many: içinden, varsayılan stratejinin delete_all olduğu (geri aramalarını çalıştırmadan birleştirme kayıtlarını silin) dışında hiçbir şey yapmamaktır (ana kimlikleri ayarlanmış yabancı anahtarları ayarlanmış olarak bırakın).
delete
Verbage için farklı çalışır ActiveRecord::Association.has_many
ve ActiveRecord::Base
. İkincisi için, silme işlemi SQL DELETE
tüm doğrulamaları / geri aramaları yürütür ve atlar. İlki :dependent
, ilişkilendirmeye geçirilen seçeneğe göre yürütülür . Ancak, test sırasında, geri çağrıların yalnızca çalıştırıldığı delete
ve çalışılmadığı aşağıdaki yan etkiyi buldumdelete_all
dependent: :destroy
Misal:
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]]