Bir sütunda validates
doğrulamak uniqueness
için kullanabilirsiniz :
validates :user_id, uniqueness: {scope: :friend_id}
Birden çok sütundaki doğrulamanın sözdizimi benzerdir, ancak bunun yerine bir dizi alan sağlamalısınız:
validates :attr, uniqueness: {scope: [:attr1, ... , :attrn]}
Ancak , yukarıda gösterilen onaylama yaklaşımlarının bir yarış durumu vardır ve tutarlılığı sağlayamazlar. Aşağıdaki örneği düşünün:
veritabanı tablosu kayıtlarının n alanla benzersiz olması beklenir ;
her biri ayrı işlemler ( uygulama sunucuları, arka plan çalışan sunucuları veya ne kullanıyor olursanız olun ) tarafından işlenen birden çok ( iki veya daha fazla ) eşzamanlı istek, aynı kaydı tabloya eklemek için veritabanına erişim;
aynı n alanı olan bir kayıt olup olmadığını her işlem paralel olarak doğrular ;
her istek için doğrulama başarılı bir şekilde iletilir ve her işlem tabloda aynı verilerle bir kayıt oluşturur.
Bu tür davranışlardan kaçınmak için, bir db tablosuna benzersiz bir kısıtlama eklemeniz gerekir . add_index
Aşağıdaki taşımayı çalıştırarak bir (veya birden çok) alan için yardımcı ile ayarlayabilirsiniz :
class AddUniqueConstraints < ActiveRecord::Migration
def change
add_index :table_name, [:field1, ... , :fieldn], unique: true
end
end
Dikkat : Benzersiz bir kısıtlama ayarladıktan sonra bile, iki veya daha fazla eşzamanlı istek aynı verileri db'ye yazmaya çalışacaktır, ancak yinelenen kayıtlar oluşturmak yerine, bu ActiveRecord::RecordNotUnique
ayrı ayrı ele almanız gereken bir istisna oluşturur:
begin
# writing to database
rescue ActiveRecord::RecordNotUnique => e
# handling the case when record already exists
end