2012-06-29 58 views
0

我使用Authlogic,默認情況下會在登錄,電子郵件和密碼等字段中提供一些驗證(長度,唯一性,格式等)。如何在已有多個驗證的ActiveModel屬性上添加條件驗證?

我希望能夠跳過附加到其中一個屬性的所有驗證,例如,如果存在另一個屬性。

這可能嗎?例如:

validate :email, :unless => :has_openid? 

然後,它將跳過僅針對電子郵件屬性的格式,長度和唯一性驗證。

我有一個Rails應用程序3.1.X和authlogic工作3.1.0

更新:我試圖按照這篇文章,但我不能讓它正常工作: http://erikonrails.snowedin.net/?p=242

回答

0

我和authlogic這樣做的方法是通過傳遞一個塊acts_as_authentic

acts_as_authentic do |config| 
    with_options :unless => :has_openid? do  
    config.merge_validates_format_of_email_field_options 
    config.merge_validates_length_of_email_field_options 
    config.merge_validates_uniqueness_of_email_field_options 
    end 
end 
+0

是的,我可以做到這一點,但它將它連接到該屬性上的特定驗證集。例如,如果我添加一個gem或者添加任何其他驗證到電子郵件字段,那麼我還需要記住更新此塊以及...請參閱我的意思? –

+0

這很公平。當你說它「不起作用」時,你看到了什麼行爲?無論如何,它是否試圖驗證該領域? – x1a4

+0

當我按照文章保存失敗,但沒有錯誤信息,我發現它是超級怪異的...我沒有深入瞭解它,我已經放棄了這種方法,所以我不能告訴你到底發生了什麼。我正在研究編寫自己的模塊,通過所有的User.validators循環,並添加和如果/除非選項...但我發現rails源初始化凍結選項哈希[lib/active_model/validator.rb](https: //github.com/rails/rails/blob/2e62af310d98fba78f338d916f7c17996446bc40/activemodel/lib/active_model/validator.rb) –

0

我寫了一個解決辦法,並抽象出來成寶石: https://github.com/synth/conditional_attribute_validator

的Gemfile:

gem 'conditional_attribute_validator', :git => "git://github.com/synth/conditional_attribute_validator.git" 

實施例:

class User 
    include ConditionalAttributeValidator 

    validate_attributes_with_condition :login, :password, :password_confirmation, :unless => :has_another_form_of_authentication? 
end 

來源:

def validate_attributes_with_condition(*args) 
    opts = args.extract_options! 
    raise "Must have an :if or :unless option" unless opts.has_key?(:if) or opts.has_key?(:unless) 

    merge_methods = self.methods.grep(/merge_.*_options/) 
    args.each do |field| 
    merge_methods.grep(/#{Regexp.quote(field)}/).each do |m| 
     self.send(m, opts) 
    end 
    end 
end 

滑軌自動地創建merge_ ATTR基於任何驗證 _options方法已經在順序指定將選項合併到現有的va中lidation。所以我查找這些方法並遍歷它們並檢查該方法是否適用於特定的字段。如果是這樣,我會調用merge_ attr _options方法並傳入選項。

我不太在意性能,因爲這只是在初始化時執行的。