Creating Custom Validators in Rails
Finally, a post about code! I found it odd that I started a blog intended to document my coding adventures and I have yet document anything related to code at all. So, the other night I was working on a personal rails project and I ran into a situation where the available rails validations were not quite what I needed.
###Validation Rules In my model had an attribute numbers which is an array of integers. In this array each number must be unique and must be one of the valid numbers allowed.
###Custom Methods
One way to implement these validations is using
custom methods.
This is a great way to create a custom validation by using a private method in the model class
that adds errors to the model when the attribute is invalid. To do this for our uniqueness
validation rule we simply create a private validation method and call it using validate
.
While this is great(and what I originally did), I wanted to explore creating a custom validator I could use across my app since I had another model that had a similar array of numbers that follows the same validations.
###Custom Validators
The rails documentation has a great example of how to write a
custom validator.
This is what I followed to create two custom validators UniqueArrayValidator
and
InclusiveArrayValidator
. Both these validators are not specific to my project and could be used
with any array(even if the values are not integers). I placed them in app/validators
, but others
recommend putting them in lib/validators
. If you put them in your lib folder you’ll have to make
sure they’re loaded when rails starts.
Here’s our new UniqueArrayValidator
For our InclusiveArrayValidator we want to be able to pass in an array of valid values to check
against. This is easily done by passing a value in the options
hash.
Here’s our InclusiveArrayValidator
###Using Custom Validators
Now we alter our model by removing the custom method and calling our new validators just as we
would any built in rails validator. You can see we pass in the valid_values
just as we would
any other option needed for validations.
Now our numbers array is validated for uniqueness and that it only includes the values we deem valid for our use case. I hope this was helpful for anyone looking to implement a custom validator in their rails app. I’m open to suggestions on how to improve the validators, best practices, and even naming(I’m not sure inclusive is the correct way to describe that validation). Hell, maybe I missed out on a way to do this with the built in validators! Feel free to leave a comment.