2009-11-26 100 views
0

我在與驗證我的回報率模型的一個問題:ActiveRecord的自定義驗證問題

 
def save 
    self.accessed = Time.now.to_s 
    self.modified = accessed 
    validate_username 
    super 
end 
 
def validate_username 
    if User.find(:first, :select => :id, :conditions => ["userid = '#{self.userid}'"]) 
    self.errors.add(:userid, "already exists") 
    end 
end 

正如你所看到的,我把它換成了型號的保存方法,用我自己的,主叫validate_username前我稱之爲父級.save方法。我的問題是,即使添加了錯誤,Rails仍會嘗試將新行插入到數據庫中,即使用戶名是重複的。我在這裏做錯了什麼?

PS:我沒有使用validate_uniqueness_of因爲區分大小寫以下問題:https://rails.lighthouseapp.com/projects/8994/tickets/2503-validates_uniqueness_of-is-horribly-inefficient-in-mysql

更新:我試過weppos解決方案,它的工作原理,但並不像我想它。現在,該字段被標記爲不正確,但前提是所有其他字段都是正確的。我的意思是,如果我輸入了一個錯誤的電子郵件地址,例如,電子郵件字段被標記爲有問題,但用戶ID字段不是。當我提交正確的電子郵件地址時,用戶標識字段被標記爲不正確。希望你們明白我的意思:d

UPDATE2:數據應在某種程度上得到驗證,它不應該是可以插入用戶ID重複到數據庫中,不區分大小寫。用戶ID具有格式「用戶域」,例如。 「test-something.net」。不幸的是,validates_uniqueness_of :userid不起作用,它會嘗試將「test-something.net」插入到數據庫中,即使已經存在「Test-something.net」。 validate_username應該是我對此問題的(快速)解決方法,但它不起作用。 weppos解決方案確實奏效,但並不像我想要的那樣(正如我的第一次更新中所解釋的)。

還沒有想出這個呢......任何人?

最好的問候, x3ro

+0

你可以提供更多關於如何驗證數據的細節嗎? – 2009-11-27 15:50:02

回答

5

爲什麼不使用回調並保持save方法不變? 另外,避免直接的SQL值插值。

class ... < ActiveRecord::Base 

    before_save :set_defaults 
    before_create :validate_username 

    protected 

    def set_defaults 
    self.accessed = Time.now.to_s 
    self.modified = accessed 
    end 

    def validate_username 
    errors.add(:userid, "already exists") if User.exists?(:userid => self.userid) 
    errors.empty? 
    end 

end 
+0

before_create而不是before_save。否則validate_username將在所有保存中失敗。否則很好的答案。 – EmFi 2009-11-26 18:24:47

+0

好點的EmFi! – 2009-11-27 11:45:29

0

如何調用超級只有validate_username返回true或類似的東西?

 
def save 
    self.accessed = Time.now.to_s 
    self.modified = accessed 
    super if validate_username 
end 
 
def validate_username 
    if User.find(:first, :select => :id, :conditions => ["userid = '#{self.userid}'"]) 
    self.errors.add(:userid, "already exists") 
    return false 
    end 
end 

......我想,你也可以完全刪除超級調用。不確定,但你可以測試一下。