नष्ट और नष्ट के बीच अंतर


210

दोनों के बीच क्या अंतर है

@model.destroy तथा @model.delete

उदाहरण के लिए:

Model.find_by(col: "foo").destroy_all
//and
Model.find_by(col: "foo").delete_all

क्या यह वास्तव में मायने रखता है अगर मैं एक या दूसरे का उपयोग करता हूं?

जवाबों:


289

मूल रूप destroyसे मॉडल पर कोई कॉलबैक नहीं चलता है जबकि deleteऐसा नहीं है।

से रेल एपीआई :

  • ActiveRecord::Persistence.delete

    डेटाबेस में रिकॉर्ड को नष्ट कर देता है और इस उदाहरण को दर्शाता है कि कोई भी परिवर्तन नहीं किया जाना चाहिए (क्योंकि उन्हें बरकरार नहीं रखा जा सकता है)। जमे हुए उदाहरण देता है।

    पंक्ति को रिकॉर्ड की प्राथमिक कुंजी पर SQL DELETE स्टेटमेंट के साथ हटा दिया जाता है, और कोई कॉलबैक निष्पादित नहीं किया जाता है।

    ऑब्जेक्ट के पहले_destroy और after_destroy कॉलबैक या किसी को भी लागू करने के लिए: निर्भर एसोसिएशन विकल्प, #destroy का उपयोग करें।

  • ActiveRecord::Persistence.destroy

    डेटाबेस में रिकॉर्ड को नष्ट कर देता है और इस उदाहरण को दर्शाता है कि कोई भी परिवर्तन नहीं किया जाना चाहिए (क्योंकि उन्हें बरकरार नहीं रखा जा सकता है)।

    नष्ट करने के साथ जुड़े कॉलबैक की एक श्रृंखला है। यदि पहले_destroy कॉलबैक गलत है तो कार्रवाई रद्द हो जाती है और रिटर्न को नष्ट कर देता है। ActiveRecord :: अधिक जानकारी के लिए कॉलबैक देखें।


नमस्कार @ user740584 - आपके उत्तर के लिए धन्यवाद। "मॉडल पर कोई कॉलबैक चलाता है" से आपका क्या मतलब है?
BKSpurgeon

3
@BKSpurgeon का अर्थ है वह ActiveRecord :: Callbacks: api.rubyonrails.org/classes/ActiveRecord/Callbacks.html । ऐसा ही एक कॉलबैक है, model#before_destroyजिसका उपयोग destroy()कुछ शर्तों के तहत अंतिम कॉल को रोकने के लिए किया जा सकता है ।
टॉड

102

delete केवल db से वर्तमान ऑब्जेक्ट रिकॉर्ड को हटाएगा, लेकिन इसके संबद्ध बच्चे db से रिकॉर्ड नहीं करेंगे।

destroy db से वर्तमान ऑब्जेक्ट रिकॉर्ड को हटा देगा और इसके संबद्ध बच्चों को db से रिकॉर्ड भी करेगा।

उनका उपयोग वास्तव में मायने रखता है:

यदि आपकी कई अभिभावक वस्तुएं आम बच्चों की वस्तुओं को साझा करती हैं, तो destroyविशिष्ट अभिभावक वस्तु पर कॉल करने से उन बच्चों की वस्तुओं को हटा दिया जाएगा जिन्हें अन्य कई माता-पिता के बीच साझा किया जाता है।


5
शानदार जवाब। धन्यवाद। मुझे लगता है कि शब्दावली मुझे यह समझ में आएगी कि बच्चे "मारे गए" हैं। क्रूर शिशु।
BKSpurgeon

उत्पादन के अधिकांश मामलों में आप 'नष्ट' का उपयोग करना चाहते हैं
आउटसाइड_ ऑक्स

नहीं, यह आवश्यक नहीं है।
तैमूर चांगैज़

मुझे लगता है कि जिस शब्द का आपको उपयोग करना चाहिए, destroyवह वंशज है , न कि बच्चे : प्रलेखन के अनुसार, नष्ट "विशेषताओं से एक नई वस्तु बनाता है, और फिर उस पर कॉल नष्ट हो जाता है।" rubydoc.info/docs/rails/4.1.7/ActiveRecord%2FRelation:destroy
Marco Lackovic

12

जब आप किसी वस्तु पर आह्वान करते हैं destroyया 'विनाश' की प्रक्रिया शुरू करते हैं, तो यह उस वर्ग का विश्लेषण करता है जिसे आप हटा रहे हैं, यह निर्धारित करता है कि उसे निर्भरता के लिए क्या करना चाहिए, मान्यताओं से चलता है, आदि।destroy_allActiveRecordActiveRecord

जब आप आह्वान करते हैं deleteया delete_allकिसी वस्तु पर करते हैं, तो ActiveRecordकेवल DELETE FROM tablename WHERE conditionsdb के विरुद्ध क्वेरी को चलाने की कोशिश करता है , कोई अन्य ActiveRecordकार्य नहीं करता है।


4

हां, दो तरीकों के बीच एक प्रमुख अंतर है delete_all का उपयोग करें यदि आप चाहते हैं कि रिकॉर्ड बिना कॉल किए गए मॉडल कॉलबैक के बिना जल्दी से हटा दिया जाए

यदि आप अपने मॉडल कॉलबैक की परवाह करते हैं, तो नष्ट_ का उपयोग करें

आधिकारिक डॉक्स से

http://apidock.com/rails/ActiveRecord/Base/destroy_all/class

नष्ट_ल (स्थितियाँ = नील) सार्वजनिक

प्रत्येक रिकॉर्ड को इंस्टेंट करके और उसकी नष्ट विधि को कॉल करके रिकॉर्ड मिलान स्थितियों को नष्ट कर देता है। प्रत्येक ऑब्जेक्ट की कॉलबैक निष्पादित की जाती है (सहित: आश्रित एसोसिएशन विकल्प और पहले_डस्ट्रो / after_destroy ऑब्जर्वर विधियाँ)। नष्ट की गई वस्तुओं का संग्रह लौटाता है; प्रत्येक को जमे हुए किया जाएगा, यह प्रतिबिंबित करने के लिए कि कोई परिवर्तन नहीं किया जाना चाहिए (क्योंकि उन्हें बरकरार नहीं किया जा सकता है)।

ध्यान दें: जब आप एक ही बार में कई रिकॉर्ड निकाल रहे होते हैं, तो तुरंत, कॉलबैक निष्पादन, और प्रत्येक रिकॉर्ड को हटाने में समय लग सकता है। यह प्रति रिकॉर्ड कम से कम एक SQL DELETE क्वेरी (या संभवतः अधिक, आपके कॉलबैक को लागू करने के लिए) उत्पन्न करता है। यदि आप अपने संघों या कॉलबैक के लिए चिंता किए बिना कई पंक्तियों को जल्दी से हटाना चाहते हैं, तो इसके बजाय delete_all का उपयोग करें।


2

मूल रूप से "डिलीट" रिकॉर्ड हटाने के लिए डेटाबेस में सीधे एक क्वेरी भेजता है। उस स्थिति में रेल्स को यह पता नहीं होता है कि रिकॉर्ड में कौन सी विशेषताएँ हैं जो न तो हटा रही हैं और न ही यदि कोई कॉलबैक है (जैसे कि before_destroy)।

"नष्ट" विधि पारित आईडी लेती है, डेटाबेस से मॉडल को "खोज" विधि का उपयोग करके लाती है, फिर उस पर कॉल नष्ट हो जाती है। इसका मतलब है कि कॉलबैक शुरू हो गए हैं।

यदि आप कॉलबैक को ट्रिगर नहीं करना चाहते हैं या आप बेहतर प्रदर्शन चाहते हैं तो आप "डिलीट" का उपयोग करना चाहेंगे। अन्यथा (और अधिकांश समय) आप "नष्ट" का उपयोग करना चाहेंगे।


2

पहले से ही बहुत सारे उत्तर; थोड़ा और साथ कूदना चाहता था।

डॉक्स :

Has_many के लिए, नष्ट करें और नष्ट करें_ हमेशा रिकॉर्ड को नष्ट करने के तरीके को हटा दिया जाएगा ताकि कॉलबैक चलाए जा सकें। हालाँकि, डिलीट और डिलीट_ऑल या तो: डिपेंडेंट ऑप्शन द्वारा निर्दिष्ट रणनीति के अनुसार डिलीट करेगा, या यदि नहीं: डिपेंडेंट ऑप्शन दिया गया है, तो वह डिफॉल्ट स्ट्रैटेजी को फॉलो करेगा। डिफ़ॉल्ट कार्यनीति कुछ भी नहीं करना है (विदेशी कुंजी को मूल आईडी सेट के साथ छोड़ दें), has_many को छोड़कर: जहां डिफ़ॉल्ट रणनीति delete_all है (जॉइन रिकॉर्ड्स को हटाएं, उनके कॉलबैक को चलाए बिना)।

deleteVerbage के लिए अलग तरह से काम करता है ActiveRecord::Association.has_manyऔर ActiveRecord::Base। बाद के लिए, हटाएं SQL DELETEसभी मान्यताओं / कॉलबैक को निष्पादित और बायपास करेगी । पूर्व को :dependentएसोसिएशन में पारित विकल्प के आधार पर निष्पादित किया जाएगा । हालांकि, परीक्षण के दौरान, मुझे निम्नलिखित साइड इफेक्ट मिले, जहां कॉलबैक केवल चलाने के लिए थे deleteऔर नहींdelete_all

dependent: :destroy उदाहरण:

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]]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.