2009-05-29 13 views
35

अगर मैं एक Customer और Order मॉडल है जिसमें एक Customer "है कई" Orders और Order परिभाषित "अंतर्गत आता है करने के लिए" Customer, रेल में हम बात के बारे में Ordercustomer_id के माध्यम से Customer के लिए एक विदेशी कुंजी होने लेकिन हम मतलब यह नहीं है यह डेटाबेस में लागू है।रेल माइग्रेशन एप्लिकेशन में विदेशी कुंजी को परिभाषित क्यों करते हैं लेकिन डेटाबेस में नहीं?

क्योंकि रेल इसे डेटाबेस-स्तर की बाधा के रूप में परिभाषित नहीं करते हैं, तो आपके डेटा की अखंडता का उल्लंघन होने का जोखिम है, शायद आवेदन के बाहर (या यदि आप एक साथ अनुरोध प्राप्त करते हैं तो अंदर)?, जब तक कि आप बाधा को लागू नहीं करते डेटाबेस मैन्युअल रूप से।

रेलवे डेटाबेस स्तर पर विदेशी कुंजी को परिभाषित क्यों नहीं करता है या रेल को ऐसा करने का कोई तरीका है?

class Customer < ActiveRecord::Base 
    has_many :orders 
end 

class Order < ActiveRecord::Base 
    belongs_to :customer 
end 

ActiveRecord::Schema.define(:version => 1) do 

    create_table "customers", :force => true do |t| 
    t.string "name" 
    end 

    create_table "orders", :force => true do |t| 
    t.string "item_name" 
    t.integer "customer_id" 
    end 

end 

उत्तर

22

रेल कुछ सम्मेलनों को धारण करता है कि डेटा अखंडता को लागू करने के लिए डेटाबेस में नहीं किया जाना चाहिए।

उदाहरण के लिए, रेल कुछ डेटाबेस डिज़ाइनों का भी समर्थन करता है जो cannot use foreign keys, जैसे पॉलिमॉर्फिक एसोसिएशन।

असल में, रेल सम्मेलनों ने डेटाबेस को एक स्थिर डेटा स्टोरेज डिवाइस के रूप में माना है, न कि सक्रिय आरडीबीएमएस। रेल 2.0 अंत में SQL डेटाबेस की कुछ और यथार्थवादी विशेषताओं का समर्थन करता है। इसमें कोई आश्चर्य की बात नहीं है कि परिणाम यह होगा कि रेल के साथ विकास संस्करण 1.0 में उससे अधिक जटिल हो जाएगा।

+1

आप रेल 2.0 की कौन सी विशेषताओं का जिक्र कर रहे थे? – eggdrop

+0

एक विशेषता जो मैं सोच रहा हूं वह प्राथमिक कुंजी स्तंभों के लिए समर्थन है जिन्हें "आईडी" नाम नहीं दिया गया है। मैं नियमित रेल डेवलपर नहीं हूं, इसलिए मैं उनकी सभी नई सुविधाओं को ट्रैक नहीं कर रहा हूं। –

+0

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

2

यह customer_id कॉलम (स्पष्ट रूप से) बनाता है। अधिकांश भाग के लिए, हालांकि, रेलवे डेटाबेस स्तर की बजाय आवेदन स्तर पर बाधाओं और मान्यताओं को लागू करने में विश्वास करता है; यही वजह है कि डिफ़ॉल्ट रूप से कॉलम में NULL मान हो सकते हैं, भले ही आपके पास validates_presence_of या ऐसा कुछ हो। रेल के डेवलपर्स का विचार यह है कि इस तरह की बाधाओं को आवेदन द्वारा डेटाबेस द्वारा नियंत्रित किया जाना चाहिए।

+4

"रेल के डेवलपर्स का विचार यह है कि इस तरह की बाधाओं को एप्लिकेशन द्वारा नियंत्रित किया जाना चाहिए, डेटाबेस नहीं" लेकिन उनका विचार क्यों है? क्या यह डेटाबेस सबसे अच्छा नहीं है? – eggdrop

+1

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

+2

संदर्भित बाधाओं को सभी प्रमुख डेटाबेस में परिभाषित किया जा सकता है। आपकी व्याख्या समझ में नहीं आता है। – eggdrop

13

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

आवेदन स्तर सत्यापन और चेक वहां आसान, त्वरित, मानव पठनीय (सोच त्रुटि संदेश) चेक प्रदान करने के लिए हैं जो 99.99% समय में काम करते हैं। यदि आपके एप्लिकेशन को उससे अधिक की आवश्यकता है, तो आपको डेटाबेस स्तर की बाधाओं का उपयोग करना चाहिए।

मुझे लगता है कि मूल परीक्षण ढांचे के कारण यह "दर्शन" विकसित हुआ: फिक्स्चर का उपयोग करते समय विदेशी कुंजी बस एक बड़ी परेशानी साबित हुई। ऐसा लगता है कि जब "बग" एक "फीचर" बन जाता है क्योंकि कोई भी इसे ठीक नहीं करता है। (यदि मैं इतिहास का गलत इतिहास कर रहा हूं, तो कोई मुझे सही करता है।)

कम से कम, डेटाबेस समुदाय के साथ अखंडता को लागू करने के लिए रेल समुदाय के भीतर एक बढ़ती हुई आवाजाही है। Check out this blog post from last month. वह कुछ प्लगइन से भी लिंक करती है जो त्रुटियों को संभालने के लिए समर्थन प्रदान करने में सहायता करती हैं (और एक और ब्लॉग पोस्ट जो अधिक प्लगइन से लिंक होती है)। कुछ और Google खोज करें; मैंने अन्य प्लगइन देखे हैं जो विदेशी कुंजी बनाने के लिए माइग्रेशन में भी समर्थन जोड़ते हैं।

अब, कोर रेल दर्शन का हिस्सा है: सामानों के बारे में चिंता न करें जब तक आपको वास्तव में आवश्यकता न हो। बहुत सारे वेब अनुप्रयोगों के लिए, शायद यह ठीक है अगर रिकॉर्ड्स के एक छोटे (संभवतः छोटे) प्रतिशत में अमान्य डेटा होता है।जो पृष्ठ प्रभावित हो सकते हैं, वे शायद ही कभी देखे जा सकते हैं, या त्रुटि को पहले से ही सुन्दर तरीके से संभाला जा सकता है। या हो सकता है कि यह अगले 6 महीनों तक हाथों से समस्याओं को संभालने के लिए सस्ता (जैसा कि ठंडा हार्ड कैश) है, क्योंकि आवेदन अब बढ़ता जा रहा है, विकास प्रक्रियाओं को हर आकस्मिकता के लिए नियोजित करना है। असल में, यदि आपके उपयोग के मामले इसे सभी महत्वपूर्ण नहीं लगते हैं, और यह वास्तव में केवल रेस स्थिति के कारण हो सकता है जो 1/10000000 अनुरोध हो सकता है ... अच्छा, क्या यह इसके लायक है?

तो मेरी भविष्यवाणी यह ​​है कि उपकरण डिफ़ॉल्ट रूप से पूरी स्थिति को बेहतर तरीके से संभालने के लिए उभरेंगे, और आखिरकार ये रेल 3 में विलय हो जाएंगे। इस बीच, यदि आपके ऐप को वास्तव में इसकी आवश्यकता है, तो उन्हें जोड़ें। यह थोड़ा परीक्षण सिरदर्द का कारण बन जाएगा, लेकिन कुछ भी नहीं जो आप मोजे और स्टब्स से नहीं मिल सकते हैं। और यदि आपके ऐप को वास्तव में इसकी आवश्यकता नहीं है ... ठीक है आप पहले से ही अच्छे हैं। :)

+0

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

4

एक गलती बहुत से लोगों को मॉडल के साथ माइग्रेशन भ्रमित कर रहा है। माइग्रेशन बस डेटाबेस को संशोधित करते हैं, और आपके द्वारा परिभाषित मॉडल के साथ कुछ लेना देना नहीं है। इस भ्रम के परिणामस्वरूप, बहुत से विदेशी कुंजी प्लगइन्स मॉडल को माइग्रेशन के साथ जोड़ते हैं और बहुत अधिक जादुई सामान करते हैं।

माइग्रेशन के लिए, मैं http://github.com/matthuhiggins/foreigner/tree/master का उपयोग करूंगा। रेल के साथ काम करने के लिए विदेशी कुंजी प्राप्त करने के लिए आपको अपने मॉडल बदलने की जरूरत नहीं है।

6

उद्योग में कई दशकों के बाद, मैं दृढ़ता से मानता हूं कि एक अच्छा डेटाबेस डिज़ाइन कई समस्याओं से एक एप्लिकेशन को सहेज लेगा, खासकर जब यह संवर्द्धन से गुजरता है। यदि यह ज्ञात है कि एक विशेष बाधा प्रोग्रामिंग पर्ची के बाद भी डेटाबेस अखंडता रखेगी (मुझे यकीन है कि मैं ऐसा करने वाला अकेला नहीं हूं), तो यदि संभव हो तो इसे सभी माध्यमों पर लागू किया जाना चाहिए। इसलिए मैं लोगों को कभी भी संभव होने पर विदेशी कुंजी का उपयोग करने के लिए प्रोत्साहित करता हूं। मैं डेटा अखंडता प्रदान करने के लिए परीक्षणों का उपयोग करने पर भी विचार करूंगा। हम सभी को मर्फी के कानून के बारे में पता है।

+0

आपके अनुभव को साझा करने के लिए धन्यवाद, बहुत सराहना की, महोदय। –