2012-03-08 163 views
0

我試圖在我的應用程序上使自定義驗證程序工作。Rails 3 - 自定義驗證程序

我已經配置好我的config.autoload.paths,它加載正常。

問題出在驗證器本身。

結果的

binding pry

instance variables: @attributes @options @with 
locals: _ _dir_ _ex_ _file_ _in_ _out_ _pry_ attribute record value 
[12] pry(#<FileCountValidator>)> value 
=> [#<Attachment id: 60, description: nil, file: "cache_600_1__img_948867_5770137d84a6c79ac825886938e...", attachable_type: "Post", attachable_id: 15, created_at: "2012-03-10 14:50:54", updated_at: "2012-03-10 14:50:54">, 
#<Attachment id: 61, description: nil, file: "cache_600_1__img_948867_90f64e01b9c871ec656a884e015...", attachable_type: "Post", attachable_id: 15, created_at: "2012-03-10 14:50:54", updated_at: "2012-03-10 14:50:54">, 
#<Attachment id: 62, description: nil, file: "cache_600_1__img_948867_85eda3946c27fa90566403ac941...", attachable_type: "Post", attachable_id: 15, created_at: "2012-03-10 14:50:54", updated_at: "2012-03-10 14:50:54">, 
#<Attachment id: nil, description: nil, file: nil, attachable_type: "Post", attachable_id: 15, created_at: nil, updated_at: nil>] 
[13] pry(#<FileCountValidator>)> value > @with 
TypeError: compared with non class/module 
from /home/kleber/.rvm/gems/ruby-1.9.3-p125/gems/activerecord-3.2.1/lib/active_record/relation/delegation.rb:20:in `>' 
[14] pry(#<FileCountValidator>)> value.size > @with 
=> true 
[15] pry(#<FileCountValidator>)> value.size 
=> 4 
[16] pry(#<FileCountValidator>)> @with 
=> 3 
[17] pry(#<FileCountValidator>)> 

所以,我試圖讓這個comparisson正是像我一樣的撬調試控制檯上。

def validate_each(record, attribute, value) 
    #binding.pry 
    record.errors.add(attribute,"#{@with} attachments per post only. #{attribute['file'].size} detected.") if value.size > @with 
    end 

但這樣做,返回我的錯誤:

NoMethodError (undefined method `size' for nil:NilClass): 
    lib/validators/file_count_validator.rb:11:in `validate_each' 
    app/controllers/posts_controller.rb:61:in `block in update' 
    app/controllers/posts_controller.rb:60:in `update' 

還有什麼辦法趕value它獲得進入validate_each方法之前?

+0

什麼'size.inspect'&'value.inspect'顯示第一個驗證? – ScottJShea 2012-03-08 23:26:49

+0

@ScottJShea請看看我上面的編輯。 – 2012-03-09 05:45:51

+0

'nil:NilClass'的undefined方法大小應該歸屬於'attribute ['file']。size'。我認爲你不需要使用它,而是使用'value.size'作爲'record.errors.add(attribute,「#每個帖子的#{@ with}附件,#{value.size}檢測到的)。 value.size> @ with' – prasvin 2012-03-10 15:21:34

回答

2

對不起,但通過的值似乎是正確的。 value意味着該記錄的那個屬性的值,即record.send(attribute)應該等於該值。

調用validates :attachments, :photo_count => 2不會發送2到validate_each方法作爲參數value。你可以做:photo_count => true,這是我通常做的,甚至是:photo_count => "foo"。您的validates聲明中的photo_count用於規定驗證程序將通過傳遞嵌入選項哈希中的值(即,用於陳述示例的2或true或「foo」)來調用。

這裏有一個方法沒有通過驗證器的限制

創建一個Constants類並定義MAX_ATTACHMENTS常量。我通常在models/constants.rb。

class Constants 
    MAX_ATTACHMENTS = 1 
end 

然後,在驗證,你可以做

class PhotoCountValidator < ActiveModel::EachValidator 
    def validate_each(record, attribute, value) 
    record.errors.add(attribute,"#{Constants::MAX_ATTACHMENTS} attachments per post only.") if record.send(attribute).size > Constants::MAX_ATTACHMENTS 
    end 
end 

是傳遞參數的驗證另一種方式:

validates :attachments, :photo_count => 3 #desired_limit 

佔優PhotoCountValidator類初始化方法,並初始化一個類變量:

def initialize(options) 
    @@max_objects = options[:with] # the options hash will be as {:attributes=>[:attachments], :with=>3}, where :with contains the desired limit passed 
    super 
end 

然後validate_each方法中:

record.errors.add(attribute,"#{@@max_objects} attachments per post only.") if record.send(attribute).size > @@max_objects 
+0

但有沒有辦法以':limit'的方式傳遞參數作爲我想要的方式?無論如何,照你說的做事可以奏效。我會嘗試。 – 2012-03-09 07:51:40

+0

@Kleber S.:查看更新 – prasvin 2012-03-09 08:31:54

+0

第一個選項通過限定一個定義的常量,返回下面的錯誤'未初始化的常量LimitValidator :: Constants' – 2012-03-09 19:17:51