क्या मैं पटरियों में कैस्केड हटाने की स्थापना कर सकता हूं?


88

मुझे पता है कि यह शायद इंटरनेट पर कहीं है, लेकिन मैं यहां स्टाकेवरफ्लो पर जवाब नहीं पा सकता हूं, इसलिए मैंने सोचा कि मैं यहां ज्ञान के आधार को थोड़ा बढ़ा सकता हूं।

मैं रूबी और रेल्स के लिए नौसिखिया हूं, लेकिन मेरी कंपनी इसमें काफी निवेश कर रही है इसलिए मैं इसे थोड़ा और विस्तार से जानने की कोशिश कर रहा हूं।

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

तो सबसे हालिया कार्य जो मैंने स्वयं दिया है, यह पता लगाना है कि कैसे कैस्केडिंग डिलीट करने के लिए रेल डेटाबेस मॉडल को कॉन्फ़िगर करना है? क्या ऐसा करने का एक आसान तरीका है? या मुझे MySql में जाकर इसे सेट करना होगा?

जवाबों:


103

आप इस पर भी निर्भर विकल्प सेट कर सकते हैं: delete_all : delete_all सभी चाइल्ड रिकॉर्ड को हटाने के लिए एक एकल SQL स्टेटमेंट जारी करेगा। इसके उपयोग के कारण: delete_all आपको बेहतर प्रदर्शन दे सकता है।

has_many :memberships, dependent: :delete_all

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

@ जॉन - आशा है कि संपादन भ्रम को स्पष्ट करते हैं। यह बात बताने के लिए धन्यवाद।
माइक ब्रीन डे

26
सुनिश्चित करें कि आप उपयोग करने के लिए :delete_allऔर इसके बीच के अंतर को समझते हैं :destroy। दोनों बच्चे की सदस्यता का कारण बनेंगे (1 स्तर हटाए जाने के लिए [उद्धरण वांछित] और nनष्ट करने के लिए (यदि उनके बच्चों के आश्रित विध्वंस हैं)) को डेटाबेस से हटा दिया :destroyजाएगा , लेकिन प्रत्येक बच्चे की वस्तु को तुरंत रोक देगा और पहले किसी भी कॉलबैक को चलाएगा, जबकि :delete_allसीधे चलेगा डेटाबेस में SQL DELETE स्टेटमेंट। :destroyउस वजह से धीमी है, लेकिन यह आपको एक रिकॉर्ड नष्ट होने पर कॉलबैक करने की अनुमति देता है। एक छोर पर परिधि की परिक्रमा और दूसरे पर संभावित n ^ x तात्कालिकता।
jstim

2
मेरा सुझाव है कि डेटाबेस विदेशी कुंजी भी स्थापित करना। इस तरह से रिकॉर्ड एक ऑपरेशन के साथ हटा दिए जाते हैं। नीचे दिया गया जवाब देखें जो मैंने पोस्ट किया है।
हेंड्रिक

66

हाँ, आप कर सकते हैं, यदि आप has_many जैसे रिश्ते का उपयोग कर रहे हैं, तो आप ऐसा करते हैं

has_many :memberships, dependent: :destroy

डैन, तो मुझे लगता है कि मेरा अगला सवाल यह है कि क्या मैं एक db माइग्रेट कमांड चलाता हूं जो वास्तव में db में सेट होगा? या कैस्केडिंग पूरी तरह से रेल द्वारा संचालित है?
१६:५० पर मैट_देव

हाँ, यह रेल द्वारा नियंत्रित किया जाता है। (Do यकीन है कि तुम सच में हमेशा हर संबंधित पंक्तियों का हटाया जाना है, हालांकि जरूरत है।)
स्टीन जी Strindhaug

@Matt - has_many लाइन आपके मॉडल वर्ग में होनी चाहिए, माइग्रेशन आपके लिए यह नहीं जोड़ेगा।
गैरेथ

मैं इस समाधान को पसंद करता हूं क्योंकि यह भी काम करता है अगर आश्रित मॉडल का एक और has_many संबंध है
tpei

25

प्रदान किए गए उत्तर के विपरीत मैं अत्यधिक सुझाव देता हूं कि यह डेटाबेस स्तर पर भी कर रहा है। यदि आपके पास अलग-अलग प्रक्रियाएं या एक बहु थ्रेडेड वातावरण है, तो ऐसा हो सकता है कि रिकॉर्ड ठीक से हटाए नहीं गए हैं। इसके अलावा डेटाबेस विदेशी कुंजी बहुत से डेटा को हटाते समय चीजों को तेजी से आगे बढ़ाती है।

सुझाए गए उत्तर में ऐसा करें:

has_many :memberships, dependent: :delete_all

हालाँकि, foreign_keyमाइग्रेशन में सेटअप करना भी सुनिश्चित करें । इस तरह डेटाबेस आपके लिए रिकॉर्ड को स्वचालित रूप से हटाने का ध्यान रखता है।

सदस्यता हटाए जाने पर मूल्यों को शून्य करने के लिए, मान लें कि आपके पास एक उपयोगकर्ता मॉडल है:

add_foreign_key :users, :memberships, on_delete: :nullify

जब भी कोई सदस्यता हटाई जाती है तो आप सभी मॉडल भी हटा सकते हैं

add_foreign_key :users, :memberships, on_delete: :cascade

तो क्या मैं "has_many: सदस्यता, निर्भर:: Delete_all" और "add_foreign_key: उपयोगकर्ताओं,: सदस्यताएँ, on_delete:: झरना" दोनों का उपयोग कर सकता हूं? क्या यह अच्छा चलेगा?
रुबिकॉन

2
आपको delete_allमॉडल में सेटअप करने की भी आवश्यकता नहीं होगी । विदेशी कुंजी डेटाबेस स्तर पर आपके लिए सब कुछ ठीक से हटाने का ध्यान रखेगी।
हेंड्रिक

3
जब आप दोनों करते हैं तो मैं उत्सुक हूं। ऐसा लगता है कि इसका नकारात्मक प्रभाव नहीं होना चाहिए, लेकिन क्या किसी को एआर और डीबी दोनों स्तर के अभ्यास के साथ बुरा अनुभव हुआ है?
जेम्स क्लेन

1
डेटाबेस स्तर वह है जिसकी मुझे तलाश थी। यह मेरी राय में स्वीकृत उत्तर होना चाहिए। दूसरों को ऐसा लगता है कि वे केवल तभी काम करते हैं जब मेरे प्रश्न मानक ActiveRecord संचालन से चिपक जाते हैं।
ब्रेट बीटी

10

बस यह ध्यान रखें कि delete_all बच्चे के रिकॉर्ड पर किसी भी कॉलबैक (जैसे पहले_डस्ट्रो और after_destroy) को निष्पादित नहीं करेगा।


6

ऐसा लगता है कि यह प्लगइन आपको वह चीज़ दे सकता है जो आप ढूंढ रहे हैं यदि आप चाहते हैं कि वास्तविक डेटाबेस संरचना में परिलक्षित कैस्केडिंग हट जाए:

http://www.redhillonrails.org/foreign_key_migrations.html

माइग्रेशन में इसका उपयोग करने का प्रारूप कुछ इस प्रकार होगा:

create_table :orders do |t|
  t.column :customer_id, :integer, :on_delete => :set_null, :on_update => :cascade
  ...
end

5
वह लिंक मर चुका है लेकिन यह एक नया विकल्प है: github.com/matthuhiggins/foreigner
gdelfino
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.