I’m trying to make a custom validator work on my app.
I have already configured my config.autoload.paths and it is loading fine.
The problem is with the validator itself.
Result of 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>)>
So, I trying to make this comparisson exactly like I did on the pry debug console.
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
But doing this, return me the error:
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'
Are there any way to catch the value before it get enters the validate_each method?
Sorry, but the value being passed seems to be correct.
valueis meant to be the value of that attribute for that record, i.e.record.send(attribute)should be equal to the value.Calling
validates :attachments, :photo_count => 2does not send 2 to thevalidate_eachmethod as argumentvalue. You could do:photo_count => true, which is what I generally do, or even:photo_count => "foo". Thephoto_countin yourvalidatesstatement serves to provide that the validator is to be called by passing the value(i.e. 2 or true or “foo” for stated examples) embedded in the options hash.Here’s a way without passing a limit to the validator.
Create a
Constantsclass and defineMAX_ATTACHMENTSconstant. I usually have it at models/constants.rb.Then, in the validator, you could do
Another way that passes a parameter to a validator:
Override the initialize method for PhotoCountValidator class, and initialize a class variable :
Then within the
validate_eachmethod :