15

मैं अपने प्रवास फ़ाइल में निम्न है अशक्त स्तंभ के लिए डाटाबेस अद्वितीय सूचकांक मिलानरेल विशिष्टता बाधा और

def self.up 
    create_table :payment_agreements do |t| 
     t.boolean :automatic, :default => true, :null => false 
     t.string  :payment_trigger_on_order 
     t.references :supplier 
     t.references :seller 
     t.references :product 
     t.timestamps 
    end 
    end 

मैं यह सुनिश्चित करना है कि यह अद्वितीय है अगर एक product_id निर्दिष्ट किया जाता है लेकिन मैं यह भी अशक्त तो अनुमति देना चाहते हैं चाहते हैं मैं अपने मॉडल में निम्नलिखित है:

validates :product_id, 
      :uniqueness => true, 
      :allow_nil => true 

अच्छा काम करता है, लेकिन मैं तो माइग्रेशन फ़ाइल

add_index :payment_agreements, :product_id, :unique => true 
लिए एक सूचकांक जोड़ना चाहिए

स्पष्ट रूप से यह अपवाद फेंक देगा जब product_id के लिए दो शून्य मान डाले जाएंगे। मैं बस माइग्रेशन में इंडेक्स को छोड़ सकता हूं लेकिन फिर मुझे यह दिखाया गया है कि मुझे उसी उत्पाद_आईडी के साथ दो पेमेंट एग्रीमेंट मिलेगा जैसा कि यहां दिखाया गया है: Concurrency and integrity

मेरा प्रश्न यह है कि इससे निपटने का सबसे अच्छा/सबसे आम तरीका क्या है समस्या

+0

यह सवाल http://stackoverflow.com/questions/191421/how-to-create-a-unique-index-on-a-null-column को – x1a4

+1

validates_uniqueness_of समान है अगर = > lambda {! self.product_id.nil? } – user386660

उत्तर

0

कुछ प्रमुख डेटाबेस सिस्टम एक अद्वितीय इंडेक्स को एकाधिक एनयूएलएल रखने की अनुमति नहीं देते हैं: अद्वितीय एनयूएलएल के साथ-साथ गैर-एनयूएलएल पर भी लागू होता है। डेटाबेस स्तर पर इसके आसपास के तरीके हैं (उदा।, ट्रिगर्स, या एक गणना कॉलम; link text देखें)।

आप इसे एप्लिकेशन स्तर पर संबोधित कर सकते हैं और एक सत्यापन में डाल सकते हैं जो विशिष्टता के लिए जांच करता है यदि product_id शून्य नहीं है।

validate :enforce_unique_product_id 
def enforce_unique_product_id 
    if (!self.product_id.nil? && 
     PaymentAgreement.exists?(:conditions=>['product_id = ?', self.product_id])) 
    errors.add_to_base('There is already an agreement with product id " + 
         self.product_id) 
    end 
end 

(अद्यतन: के रूप में zed_0xff से कहा, MySQL सबसे अधिक इस्तेमाल किया भंडारण इंजन में एक अद्वितीय सूचकांक में कई NULLs अनुमति देता है।)

11

इसे अपने डाटाबेस सर्वर पर निर्भर करता है। mysql के लिए के रूप में :

एक अद्वितीय सूचकांक की कोई समस्या ऐसी है कि सूचकांक में सभी मूल्यों अंतर होना चाहिए बनाता है। एक त्रुटि तब होती है जब आप किसी कुंजी पंक्ति के साथ एक नई पंक्ति जोड़ने का प्रयास करते हैं जो मौजूदा पंक्ति से मेल खाता है। यह बाधा बीडीबी स्टोरेज इंजन को छोड़कर NULL मानों पर लागू नहीं होती है। अन्य इंजनों के लिए, एक अद्वितीय इंडेक्स कॉलम के लिए एकाधिक NULL मानों की अनुमति देता है जिनमें न्यूल हो सकता है। , Product_id: