Creating Custom Validations in Rails

Carl-Brain Egebe
3 min readOct 27, 2021

Rails validations help prevent the entry of “bad” data into a database. Now, what exactly makes data “bad” depends on the rules set for data trying to get into that database.

The way validations works is very similar to how TSA checkpoints work. Rules and guidelines are setup and at a checkpoint, it is determined whether or not that data or person is allowed to get through depending on those rules/guidelines.

In rails, the validation rules are set up in the models. This would be what the Department of Homeland Security is to the TSA checkpoint. In this example, I’m going to use a model called Passenger. The Passenger table will have the following attributes: name, passport, luggage_weight, and luggage_contents. Name being a string, passport being a boolean, luggage_weight being an integer, and luggage_contents being a string of names of all contents in luggage.

Here’s what some of the basic validations will look like:

On line 3, a check is just being made to make sure the passenger has a name. On line 4, a check is being made in order to validate the luggage weight. The weight must be with-in the range of 0–40. If not, that passenger will be deemed invalid and wont be allowed to pass. Sometimes, in rails, the messages aren’t really helpful in explaining the reason for invalidation of a record, so we have to create our own error messages, thus the message key in the inclusion hash on line 4. The default error message for the validation on line 4 and 5 is: “myfield is not included in the list”… not very helpful.

Now if a passenger comes along without any luggage, they should be able to pass the validation for luggage_weight, However, since the value of luggage_weight for that user would be “nil” and not between 0–40, they would become invalid. We can prevent this by adding “allow_nil => true” to the validation.

Now, for the custom validations. These are validations created for not so simple cases, a lot can be taken into account when creating these validations. I’m going to create a custom validation which goes through all the luggage_contents and make sure the luggage doesn’t contain the “unallowed item”

When declaring a custom validator, “validate” is used instead of “validates”. To better understand what’s going on in line 12, a sample of luggage_contents would look like “socks, shoes, sweater, book, toothbrush”. “Self” is used to access the attributes required to set up the validation. If the record doesn’t make it through the validation, the informative message is created, specifying what attribute caused the invalidation(line 15).

Lets say the Dep of HLS finds out there is a possibility of a certain individual named ‘Edward Scissorhands’ going through the TSA checkpoints. They would then have to add a new rule for that specific individual. That custom validation would look like this:

We see here that its possible to access multiple attributes in order to create a validation for a single attribute. If a record is trying to get created with the name attribute of “Edward Scissorhands” and a luggage_content attribute not containing “gloves”, that record would be deemed invalid. Otherwise, the Edward would be cleared and allowed to board. In the case of Rails, that record would be saved in the database.

--

--