आप एक कॉलम पर validates
मान्य करने के लिए उपयोग कर सकते हैं uniqueness
:
validates :user_id, uniqueness: {scope: :friend_id}
एकाधिक स्तंभों पर सत्यापन के लिए सिंटैक्स समान है, लेकिन आपको इसके बजाय फ़ील्ड की एक सरणी प्रदान करनी चाहिए:
validates :attr, uniqueness: {scope: [:attr1, ... , :attrn]}
हालांकि , ऊपर दिखाए गए सत्यापन दृष्टिकोणों में एक दौड़ की स्थिति है और स्थिरता सुनिश्चित नहीं कर सकती है। निम्नलिखित उदाहरण पर विचार करें:
डेटाबेस तालिका रिकॉर्ड n क्षेत्रों द्वारा अद्वितीय माना जाता है ;
एकाधिक ( दो या अधिक ) समवर्ती अनुरोध, प्रत्येक ( एप्लिकेशन सर्वर, बैकग्राउंड वर्कर सर्वर या आप जो भी उपयोग कर रहे हैं ) अलग-अलग प्रक्रियाओं द्वारा संभाले जाते हैं, तालिका में एक ही रिकॉर्ड सम्मिलित करने के लिए डेटाबेस तक पहुंचते हैं;
यदि समान एन फ़ील्ड के साथ कोई रिकॉर्ड है, तो समानांतर में प्रत्येक प्रक्रिया मान्य होती है ;
प्रत्येक अनुरोध के लिए सत्यापन सफलतापूर्वक पारित किया गया है, और प्रत्येक प्रक्रिया समान डेटा के साथ तालिका में एक रिकॉर्ड बनाती है।
इस तरह के व्यवहार से बचने के लिए, किसी व्यक्ति को db तालिका में एक अद्वितीय अवरोध जोड़ना चाहिए । आप इसे add_index
निम्न माइग्रेशन चलाकर एक (या एकाधिक) फ़ील्ड के लिए सहायक के साथ सेट कर सकते हैं :
class AddUniqueConstraints < ActiveRecord::Migration
def change
add_index :table_name, [:field1, ... , :fieldn], unique: true
end
end
कैविएट : एक अद्वितीय बाधा निर्धारित करने के बाद भी, दो या अधिक समवर्ती अनुरोध db को एक ही डेटा लिखने की कोशिश करेंगे, लेकिन डुप्लिकेट रिकॉर्ड बनाने के बजाय, यह एक ActiveRecord::RecordNotUnique
अपवाद को बढ़ाएगा , जिसे आपको अलग से संभालना चाहिए:
begin
# writing to database
rescue ActiveRecord::RecordNotUnique => e
# handling the case when record already exists
end