delete_all vs नष्ट_आल?


192

मैं एक तालिका से रिकॉर्ड हटाने के लिए सबसे अच्छा तरीका ढूंढ रहा हूं। उदाहरण के लिए, मेरे पास एक उपयोगकर्ता है जिसकी उपयोगकर्ता आईडी कई तालिकाओं में है। मैं इस उपयोगकर्ता और हर रिकॉर्ड को हटाना चाहता हूं जिसमें सभी तालिकाओं में उसकी आईडी है।

u = User.find_by_name('JohnBoy')
u.usage_indexes.destroy_all
u.sources.destroy_all
u.user_stats.destroy_all
u.delete

यह काम करता है और सभी तालिकाओं से उपयोगकर्ता के सभी संदर्भों को हटा देता है, लेकिन मैंने सुना है कि destroy_allबहुत प्रक्रिया भारी थी, इसलिए मैंने कोशिश की delete_all। यह केवल उपयोगकर्ता को अपनी स्वयं की उपयोगकर्ता तालिका से हटाता है और idअन्य सभी तालिकाओं से शून्य बना दिया जाता है, लेकिन उनमें रिकॉर्ड को बरकरार रखता है। क्या कोई इस तरह के कार्य को करने के लिए सही प्रक्रिया को साझा कर सकता है?

मैं देखता हूं कि सभी संबद्ध वस्तुओं पर फ़ंक्शन destroy_allकॉल करता है destroyलेकिन मैं सही दृष्टिकोण की पुष्टि करना चाहता हूं।

जवाबों:


243

तुम सही हो। यदि आप उपयोगकर्ता और सभी संबंधित वस्तुओं को हटाना चाहते हैं -> destroy_all हालांकि, यदि आप सभी संबद्ध वस्तुओं को दबाए बिना उपयोगकर्ता को हटाना चाहते हैं ->delete_all

इस पद के अनुसार: रेल: आश्रित =>: वीएस को नष्ट: आश्रित =>: डिलीट_ल

  • destroy/ destroy_all: इस ऑब्जेक्ट के साथ संबंधित ऑब्जेक्ट्स को उनके नष्ट विधि को कॉल करके नष्ट कर दिया जाता है
  • delete/ delete_all: सभी संबंधित वस्तुओं को उनके कॉल के बिना तुरंत नष्ट कर दिया जाता है: विध्वंस विधि

80
यह भी ध्यान दिया जाना चाहिए कि 1) कॉलबैक का उपयोग करते समय कॉल नहीं किया जाता है delete_all, और 2) destroy_allसभी रिकॉर्ड्स को इंस्टैंट करता है और एक बार में उन्हें नष्ट कर देता है, इसलिए बहुत बड़े डेटासेट के साथ, यह दर्दनाक रूप से धीमा हो सकता है।
डायलन मार्को

मान लें कि मैं मॉडल में पहले से_स्ट्रोय विधि चला रहा हूं - यदि मैं delete_all का उपयोग करता हूं तो यह विधि नहीं चलेगी? दूसरी बात यह है कि अगर मैं अपने मॉडल में पहले से काम करने वाली विधि को नियोजित करता हूं, तो क्या मैं रेल कंसोल में डिलीट या डिलीट_ऑल चलाऊंगा?
BKSpurgeon

23

delete_all एक एकल SQL DELETE कथन है और इससे अधिक कुछ नहीं। नष्ट करने के लिए सभी कॉल के परिणाम: (यदि आपके पास एक है) पर कम से कम NUM_OF_RESULTS SQL कथन हो सकते हैं।

यदि आपको बड़े डेटासेट पर नष्ट_ () जैसे कुछ कठोर करना है, तो मैं शायद ऐप से नहीं करूंगा और इसे मैन्युअल रूप से देखभाल के साथ संभालूंगा। यदि डेटासेट छोटा है, तो आप उतना नुकसान नहीं करेंगे।


16

इस तथ्य से बचने के लिए कि destroy_allसभी अभिलेखों को तत्काल तैयार करता है और उन्हें एक बार में नष्ट कर देता है, आप इसे सीधे मॉडल वर्ग से उपयोग कर सकते हैं।

इसलिए इसके बजाय:

u = User.find_by_name('JohnBoy')
u.usage_indexes.destroy_all

तुम कर सकते हो :

u = User.find_by_name('JohnBoy')
UsageIndex.destroy_all "user_id = #{u.id}"

परिणाम सभी संबंधित रिकॉर्ड को नष्ट करने के लिए एक क्वेरी है


1
क्या यह संबंधित रिकॉर्ड पर नष्ट कॉलबैक को बुलाएगा, या इसके UsageIndex.destroy_allसाथ बराबर है UsageIntex.delete_all?
मैग्ने

UsageIndex.destroy_allअब रेल के बाद से उपलब्ध नहीं है 3
fabriciofreitag

1

मैंने एक छोटा रत्न बनाया है जो कुछ परिस्थितियों में संबंधित रिकॉर्ड को मैन्युअल रूप से हटाने की आवश्यकता को कम कर सकता है।

यह रत्न ActiveRecord संघों के लिए एक नया विकल्प जोड़ता है:

आश्रित:: delete_recursively

जब आप किसी रिकॉर्ड को नष्ट करते हैं, तो इस विकल्प का उपयोग करने से जुड़े सभी रिकॉर्ड पुनरावर्ती रूप से हटा दिए जाएंगे (यानी मॉडल भर में), उनमें से किसी को भी इंस्टेंट किए बिना।

ध्यान दें कि, आश्रित की तरह:: हटाएँ या निर्भर:: delete_all, यह नया विकल्प आश्रित रिकॉर्ड के आसपास / पहले / after_destroy कॉलबैक को ट्रिगर नहीं करता है।

हालांकि, निर्भर होना संभव है:: मॉडल की एक श्रृंखला के भीतर कहीं भी संघों को नष्ट कर दें जो अन्यथा निर्भर के साथ जुड़े हुए हैं:: delete_receursively। नष्ट करने का विकल्प आम तौर पर लाइन के ऊपर या नीचे कहीं भी काम करेगा, सभी संबंधित रिकॉर्डों को त्वरित और नष्ट कर देगा और इस प्रकार उनकी कमियां भी ट्रिगर करेगा।


यह शानदार है! मुझे आश्चर्य है कि अधिक लोगों ने इसे जीथब पर क्यों नहीं देखा / अभिनीत किया / भुनाया .. क्या यह अभी भी अच्छी तरह से काम कर रहा है?
मैग्ने

@Magne धन्यवाद! यह काम करना चाहिए। परीक्षण रूबी 2.4.1 और रेल 5.1.1 पर चलते हैं। अब तक मैंने इसे केवल निजी तौर पर इस्तेमाल किया है और प्रमुख उत्पादन ऐप में नहीं, इसलिए प्रमुख संस्करण "0" है, लेकिन मैंने कभी किसी मुद्दे पर ध्यान नहीं दिया। यह काफी सरल भी है, इसलिए यह ठीक होना चाहिए।
Janosch

ठंडा। :) मैं रूबी 2.3.1, और 'रेल', '~> 4.1.14' पर एक परियोजना चला रहा हूं, और अन्य रत्नों के कारण एक्टिवरकॉर्ड (~> 4.1.0) पर भरोसा करने के लिए दुखी हूं। मैं देखता हूं कि delete_recursively को 0.9.0 पर हल किया गया है। क्या इसका कोई पुराना संस्करण है जो एक्टिवरकॉर्ड 4.1 के साथ काम करेगा? मुझे जीथब पर रिलीज़ टैब में कोई भी नहीं मिला।
मैग्ने

1
@ मेन ने पाया कि यह वास्तव में 4.1.14 के रूप में एक्टिवरकॉर्ड के लिए काम करता है और मणि संस्करण 1.0.0 को आराम से निर्भरता के साथ जारी किया है। ध्यान रखें कि रेल की 4.1 शाखा अब सुरक्षा अद्यतन प्राप्त नहीं करती है, हालांकि।
जोंसक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.