ActiveRecord Validation for MVC Architecture
Rejection hurts. No sense in mincing words. We’ve all been there. “What’s the worst that could happen, they say ‘no’?”
Standards can be unforgiving at times, but they can also be extremely useful when establishing classes in MVC software applications. As programmers, we spend so much time fine-tuning our class methods so that they can produce accurate and valuable insights, it would be a shame for a class instance that has been saved to the database to unexpectedly fall outside of certain attribute expectations that have not been defined and throw off a crucial piece of our class’ logic.
We are so careful to establish the relationships between our models, we may as well hard-code our class attribute expectations so that we don’t wind up with a handful of outlier database-instances muddying up our insights. When designing the application and its models, real world examples are taken into consideration, and this may lead to certain assumptions being made about the range of values that will be entered for each attribute. If no control is set over this, the database can so convoluted, it will make the Wild Wild West look like the regular West. This is where ActiveRecord Validations come in handy when we are establishing the schema for our database.
In the above example, a Belieber class is defined as a core model of a new application for music adorers, and for this particular class, our instances must meet rather stringent requirements defined by the implementation of ActiveRecord Validations.
The first ActiveRecord validation our class is making use of is uniqueness. In this particular case, when a new Belieber is created, our model is confirming that this particular instance does not share a nickname with an existing Belieber in our database before the new instance is saved.
The next validation in the Belieber model is presence. This ensures that each instance that is created will not have a nil value for the class attribute specified by the validation. For each new Belieber, the application wants to make sure that they are really committed enough to qualify for this model.
Numericality validation comes with a number of built-in methods that overlap the functionality of basic Ruby comparison operators. These are:
This validation proves useful when a class attribute calls for an integer value, and we want to limit the range of acceptable values. This could be based on mere user requirements for the scope of our application, or could preserve the integrity of some internal class logic that was developed with real world examples in mind, and therefore, an assumed range of values.
The last validation in the Belieber class is Inclusion. This will validate that the entry made by the user for favorite_song in the /new view matches one of the acceptable strings in our provided array. Each Belieber must prove they have worthy taste by accurately naming one of the acceptable songs when entering a value for their favorite Beibs song.
On the corresponding form for new Belieber applicants, the form_for helper is used, and a corresponding field is provided for each of the attributes specified by our validations (this form may contain fields without any validations as well). The create route defined in the Belieber Controller will take in these params, run the instance through a bit of internal logic stating that if the instance saves without any validation breaches, the application will show the new instance in the class’ show view.
However, if the the instance fails to save upon creation for not meeting any or all of the validation requirements, the built-in ActiveRecord Error Messages associated with the failed validation(s) will be shoveled into an array that will be accessible in the new view. The create logic will then redirect back to the new view — without saving the attempted instance — at which point the view can check for any error messages associated with the last attempt.
The first time visiting the Belieber class new view, no error messages exist, or have been saved to the flash[:errors] array, so the first bit of logic on the form will be skipped. However, if the user submits a form that fails any of the validations, they will be redirected right back to the new view, only this time an array of corresponding error message(s) will exist thanks to the create route logic in the Belieber Controller.
The form will recognize that flash[:errors] is not empty, and the form logic displayed below will display each pre-provided error message in a way that notifies the user which requirements were not met, and steers the user in the direction of successfully submitting a new instance.
It’s certainly no fun being at the business end of harsh standards (who hurt me?), but when they are used responsibly, standards can provide control that will preserve the relationship between real world instances and the logic that has been designed to interact with them. Validations are a powerful tool when designing an MVC application, so please, validate responsibly.