2012-04-06 16 views
6

नष्ट करने की स्थिति के तहत नष्ट हो गया है before_destroy हुक के भीतर, क्या ऑब्जेक्ट (क्लास) destroy कहा जाता है?एसोसिएशन के माध्यम से एसोसिएशन निर्भर है, जिसे

निम्नलिखित उदाहरण में, जब patient नष्ट हो जाता है, तो उनके appointments (जो मैं चाहता हूं); हालांकि मैं physician से जुड़े appointments पर physician को नष्ट करने की अनुमति नहीं देना चाहता हूं।

फिर, before_destory कॉलबैक में ऐसी जांच करने का कोई तरीका है? यदि नहीं, तो क्या कॉल के "दिशा" (यानी किसने कहा जाता है) के आधार पर इस "विनाश की जांच" को पूरा करने का कोई और तरीका है?

class Physician < ActiveRecord::Base 
    has_many :appointments, dependent: :destroy 
    has_many :patients, through: :appointments 
end 


class Patient < ActiveRecord::Base 
    has_many :appointments, dependent: :destroy 
    has_many :physicians, through: :appointments 
end 


class Appointment < ActiveRecord::Base 
    belongs_to :patient 
    belongs_to :physician 

    before_destroy :ensure_not_referenced_by_anything_important 

    private 

    def ensure_not_referenced_by_anything_important 
    unless patients.empty? 
     errors.add(:base, 'This physician cannot be deleted because appointments exist.') 
     false 
    end 
    end 
end 

उत्तर

11

बस कहते हैं:

class Physician < ActiveRecord::Base 
    has_many :appointments, dependent: :restrict_with_exception 
    has_many :patients, through: :appointments 
end 

नोट dependent: :restrict_with_exception। यह सक्रिय रिकॉर्ड को नियुक्ति रिकॉर्ड से जुड़े किसी भी चिकित्सक रिकॉर्ड को नष्ट करने से इंकार कर देगा।

the API docs और the association basics guide देखें।

+0

: एक शाखा 'रेल 4' के लिए किस्मत में में [' restrict' पदावनत किया गया था] (https://github.com/rails/rails/commit/5ad79989ef0a015fd22cfed90b2e8a56881e6c36#diff-5870816b49b90e43340607bb11ed2514R91) अगस्त 10, 2012 है। [* एसोसिएशन बेसिक्स * गाइड भी अपडेट किया गया था] (https://github.com/rails/rails/commit/a63fc94aa3689f1e781ac51411ec79a81c011d8a)। ': limit_with_exception' समान कार्यक्षमता प्रदान करता है जैसे 'प्रतिबंधित' किया गया; एक और समान विकल्प भी है, ': limit_with_error', जो किसी संबंधित ऑब्जेक्ट पर मालिक को त्रुटि जोड़ने का कारण बनता है। – user664833

15

ध्यान दें कि dependent: :destroy एक has_many :through संबंधों पर केवल संघ और नहीं जुड़े रिकॉर्ड को हटा देता है (अर्थात में शामिल होने के रिकॉर्ड हटा दिए जाएंगे, लेकिन संबद्ध रिकॉर्ड नहीं होगा)। इसलिए यदि आप patient हटाते हैं तो यह केवल appointment हटा देगा और physician नहीं होगा। the API docs में विस्तृत स्पष्टीकरण पढ़ें।

मैंने नीचे दिए गए प्रासंगिक अनुच्छेदों को चिपकाया है।

क्या हटाया गया है?

यहां एक संभावित नुकसान है: has_and_belongs_to_many और has_many :through एसोसिएशन के पास टेबल, साथ ही संबंधित रिकॉर्ड में शामिल होने के रिकॉर्ड हैं। तो जब हम इन विलोपन विधियों में से एक को कॉल करते हैं, तो वास्तव में क्या हटाया जाना चाहिए?

उत्तर यह है कि यह माना जाता है कि एक एसोसिएशन पर हटाना मालिक और संबंधित ऑब्जेक्ट्स के बीच लिंक को हटाने के बारे में है, बजाय संबंधित वस्तुओं को स्वयं के बजाय। तो has_and_belongs_to_many और has_many :through के साथ, शामिल रिकॉर्ड हटा दिए जाएंगे, लेकिन संबंधित रिकॉर्ड नहीं होंगे।

यह समझ में आता है, तो आप इसके बारे में सोचते हैं: आप food टैग बल्कि के लिए की तुलना में टैग से डेटाबेस से हटा दिया जाना चाहिए, post से अनलिंक करना चाहते हैं यदि आप post.tags.delete(Tag.find_by_name('food')) कॉल करने के लिए थे।

+0

ग्रेट स्पष्टीकरण, धन्यवाद! मुझे निर्भर होने पर कठिन समय लग रहा था:: संगठन को हटा दें और दूसरी तरफ रिकॉर्ड हटा दें। – Arel

+0

यह एक पूर्ण जवाब की तरह लगता है, हालांकि, मैंने इसे सेट अप किया है जैसा कि आपने कहा था और जब मैं रोगी को हटाने की कोशिश करता हूं (रेल व्यवस्थापक का उपयोग करके), चिकित्सक को भी हटा दिया जाता है। –