2014-07-09 61 views
1

我在我的Rails應用上使用了法官gem進行客戶端驗證。驗證我的用戶模型是這個樣子:如何使用Judge Gem配置唯一性和自定義驗證?

VALID_EMAIL_REGEX = /^[\w+\-.][email protected][a-z\d\-.]+\.[a-z]+$/i 
    VALID_USERNAME_REGEX = /^[A-Za-z\d_]+$/ 

    validates :username,  :presence => true, 
           :uniqueness => true, 
           :length => { :within => 2..49 }, 
           :format => { :with => VALID_USERNAME_REGEX, :multiline => true }, 
           :exclusion => { :in => RESERVED_HANDLERS }, :on => :create 

    validates :email,   presence: true, 
           length: { maximum: 50 }, 
           format: { with: VALID_EMAIL_REGEX, :multiline => true }, 
           uniqueness: { case_sensitive: false } 

因爲我們打了獨特的服務器我已經暴露了:用戶名和:電子郵件在初始化法官以及:

Judge.configure do 
    expose User, :username, :email 
end 

現在,這裏是問題:理想情況下,我希望電子郵件和用戶名格式在客戶端本身進行驗證,而不需要訪問服務器,但我也想在服務器端保留相同的安全措施。所以請注意我已經放入的正則表達式與rails兼容,並且我已經爲^ $ end字符設置了:multiline => true。

但這並不按預期工作。客戶端驗證不適用於1.:唯一性和2.電子郵件/用戶名格式。爲什麼會:uniqueness => true無法正常工作?

回答

0

對於正則表達式的問題:

將這個代碼在judge.rb初始化:

Judge::Validator.class_eval do 
    def to_hash 
    { 
     :kind => kind, 
     :options => get_js_compatible_options(options), 
     :messages => messages.to_hash 
    } 
    end 

    private 

    def get_js_compatible_options(options) 
    method_name = "get_js_compatible_#{self.kind}" 
    if self.respond_to? method_name, options 
     options = self.send method_name, options 
    end 
    options 
    end 

    def get_js_compatible_format(options) 
    format_options = Hash.new 
    options.each do |key, option| 
     format_options[key] = (key == :with) ? convert_regex_to_js_compatible(option) : option 
    end 
    format_options 
    end 

    def convert_regex_to_js_compatible(regex) 
    js_regex_source = regex.source.sub(/^\\A/, '^').sub(/\\z$/i, '$') 
    /#{js_regex_source}/ 
    end 
end 

然後使用這個表達式:

VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][a-z\d\-.]+\.[a-z]+\z/i 
VALID_USERNAME_REGEX = /\A[A-Za-z\d_]+\z/ 

法官會自動將其轉換爲JavaScript的兼容版本。

相關問題