2013-10-24 18 views
16

Sadece bir kaydın doğru olabileceği bir doğrulama yazmaya çalışıyorum. 'Aktif' bir boolean sütunu olan bir 'oyun' modelim var, sadece bir oyun her an aktif olabilir, bu yüzden zaten aktif bir oyun olduğunda birisi yeni bir 'oyun' kaydı oluşturmaya çalışırsa hata. Aşağıda şu anda sahip olduğum ama çalışmıyor!Raylar özel doğrulama - Sadece bir kayıt doğru olabilir

validate :active_game 

    def active_game 
    if active == true && Game.find_by(active: true) == true 
     errors[:name] = "a game is already active!" 
    end 
    end 
+0

bunu çalışmıyor ne anlama geliyor? –

cevap

9

Kayıt zaten devam ediyorsa, ID'ye karşı da kontrol etmeniz gerekir. Aksi takdirde, aktif oyunu tekrar kaydetmek başarılı olmaz çünkü mevcut olan aktif bir oyun vardır.

validate :only_one_active_game 
scope :active, where(:active => true) 

protected 

def only_one_active_game 
    return unless active? 

    matches = Game.active 
    if persisted? 
    matches = matches.where('id != ?', id) 
    end 
    if matches.exists? 
    errors.add(:active, 'cannot have another active game') 
    end 
end 
+0

Kodunuzdan bir hata alıyorum: PG :: UndefinedFunction: ERROR: operatör yok: tamsayı <> LINE 1: ... "WHERE" oyunları "." Active "= 't 'AND (id! =) –

+0

O eksik bir '?'. '' Id! = '' 'Id olmalıdır! =?'' – lightswitch05

+0

Oops, pardon! Haklısın, soru işaretini özledim. – kristinalim

0

exists? yöntemi kullanmayı deneyin. Ayrıca, add yöntemini kullanarak hatayı ekleyin.

validate :active_game 
scope :active, where(active: true) 

    def active_game 
    if active && Game.active.where("id != ?", id).exists? 
     errors.add(:name, "a game is already active!") 
    end 
    end 
+0

'id! =?' Bölümü, 'id' 'NULL' olduğunda (yani kalıcı değilken) problemlidir. http://sqlfiddle.com/#!12/ae03e/3 – kristinalim

+0

Üzgünüm, açık değildi. 'SELECT * Kitaplardan NEREDE! = NULL AND active IS TRUE;' zaten aktif bir oyun varsa, yanlış bir negatif (mevcut kaydı bulamaz) döndürür. http://sqlfiddle.com/#!12/7d865/3 Bu, çoğu DBMS için geçerli olup olmadığından emin değil, ancak bir değer olduğunu kontrol etmek için standart "IS NOT NULL" kullanmaktır. Eğer Yanlışsam beni düzelt. – kristinalim

+0

Evet, doğruyunuz – lightswitch05

43

Bunun doğru olduğunda sadece active_game benzersizliğini kontrol edebilirsiniz düşünüyorum.

validates_uniqueness_of :active_game, if: :active_game

+0

ve en zarif yolu IMHO – Rin

+0

Bu bir boolean değeri olduğu gerçeğini yararlanmak için bunu yapmak için çok cleaver yolu! –

+0

Kesinlikle kabul edilen cevap olmalı –

İlgili konular