2012-11-19 18 views
1

在我的應用程序中,有多個自定義驗證器存放在app /驗證器中,然後調用多個模型。DRY在rails中編寫許多自定義驗證器的方法

大多數情況下,我這樣做基於正則表達式的驗證,像電子郵件,手機等基本上自定義數據字符串,我需要在一個特定的格式。

例如:

class EmailValidator < ActiveModel::EachValidator 
    def validate_each(record, attribute, value) 
    unless value =~ /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i 
     record.errors[attribute] << (options[:message] || "is not a valid email format") 
    end 
    end 
end 

class IpValidator < ActiveModel::EachValidator 
    def validate_each(record, attribute, value) 
    unless value =~ /^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/ 
     record.errors[attribute] << (options[:message] || "is not a valid IP format") 
    end 
    end 
end 

這種方法的缺點是,我有幾乎相同的代碼了很多額外的文件,可以得到更大的應用煩人。

是否有更好的方法(更幹)來定義基於正則表達式的驗證,使它們可以跨模型重用?

+0

你可以把你所有的驗證在一個單一的文件'custom_validators.rb'代替使用一個文件驗證器。另一種解決方案是將它們分組在分隔符文件夾「lib/validators」或「app/validators」中,並將此文件夾添加到配置文件中的加載路徑。 –

+0

@AdrienCoquio事情是,我已經爲所有人使用了一個單獨的文件夾 - 問題是代碼重複一次又一次。唯一改變的是正則表達式和錯誤信息! –

回答

2

你可以做一個基類的正則表達式驗證:

class RegexValidator < ActiveModel::EachValidator 
    def regex_validate_each(regex, err_msg, record, attribute, value) 
    unless value =~ regex 
     record.errors[attribute] << (options[:message] || err_msg) 
    end 
    end 
end 

然後繼承它想:

class EmailValidator < RegexValidator 
    def validate_each(record, attribute, value) 
    regex_validate_each(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, "is not a valid IP format", record, attribute, value) 
    end 
end