我正在尝试在我的应用上制作自定义验证工具。
我已经配置了我的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>)>
所以,我试图使这个比较完全像我在pry调试控制台上做的那样。
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 :(得分:2)
很抱歉,但传递的值似乎是正确的。 value
意味着该记录的该属性的值,即record.send(attribute)
应该等于该值。
调用validates :attachments, :photo_count => 2
不会将validate_each
方法作为参数value
发送2。您可以执行:photo_count => true
,这是我通常所做的,甚至是:photo_count => "foo"
。 photo_count
语句中的validates
用于通过传递嵌入在选项哈希中的值(即,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类的initialize方法,并初始化一个类变量:
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