Table of contents
Revisited on May 26th, 2023
Hey guys, how've you been? It's AC, Alexandre Calaça here. I'm so excited that you landed here. Hope you enjoy this new article.
By the way, I would be glad to receive your feedback about it.
You might be interested in checking my complete list of articles.
This is the Part III of the series Creating Bulletproof Validations in Ruby on Rails with Custom Validators.
Part I provided a basic introduction to validations.
Part II showed up to provide strong foundations for the next part, which is this Part III.
In this article, we will explore how to create custom validations in separate classes with Ruby on Rails. We will cover the basic concepts of custom validators, how to set them up in your Rails application, and how to use them in your models.
By the end of this article, you will have a solid understanding of how to create custom validators in Rails and how they can benefit your application development process.
Planning of this series:
In a Ruby on Rails application, validation of input data is essential to ensure that the data is correct and meets the business requirements. Rails provides several built-in validation methods that can be used to validate various types of input data, such as numericality, presence, and format of the data. However, as the complexity of your models or the validation rules increases, using only the built-in validation methods can become challenging to manage.
To address this problem, you can create custom validation methods as separate classes that can be reused across multiple models. These custom validation classes allow you to define more complex validation rules and keep your models lean and easy to maintain. Additionally, custom validation classes promote code reuse by allowing you to define a set of validation rules in one place and then use it across multiple models..
Validations are a set of rules or conditions that are applied to input data to ensure that it meets certain criteria.
The purpose of validations is to ensure that the data entered by users or generated by the system is accurate, consistent, and safe to use.
Validations in Ruby on Rails
In Ruby on Rails, validations are used to ensure that the data entered by users is valid and meets certain criteria before it is saved to the database. This helps to maintain data integrity and prevent errors in your application.
There are basically 3 approaches to validations:
built-in validation methods
This article is going to focus on Custom validators.
Built-in validation methods
Custom validators in Ruby on Rails are custom-built validation methods that allow you to define your own validation rules for your models. These validators are separate classes that can be created in your Rails application and used in your models.
Custom validators are important in Ruby on Rails development because they enable you to define more complex validation rules beyond what is provided by the built-in Rails validation methods. For example, you may need to validate a model attribute based on some external condition or perform validation that involves multiple attributes. Custom validators allow you to write this custom validation logic and encapsulate it in a separate class, making it easy to reuse across multiple models.
Using custom validators can also help keep your models lean and focused on their core responsibilities. By separating validation logic into a separate class, you can ensure that your models are not cluttered with validation code and that their codebase remains easy to maintain.
Overall, custom validators are an essential tool in Ruby on Rails development that allow you to define your own validation rules and keep your models lean and focused. By using custom validators, you can ensure that your Rails application's input data is validated according to your specific requirements and that your code remains modular and maintainable.
To create a custom validator in Rails, you need to define a class that inherits from ActiveModel::Validator or ActiveModel::EachValidator and implement a validate method.
The validate method can take a single or multiple arguments. One of them must be the model instance being validated, and you can add error messages to the model's errors collection if the validation fails.
Let me guide you through the process with these eight simple steps, which I call "baby steps."
8 super simples steps, I called them "baby steps".
Identify what class and attribute(s) you're going to test against.
Our example is going to consider a
Product model with the following attributes:
id: integer, title: string, description: text, image_url: string, price: decimal, created_at: datetime, updated_at: datetime)Product => Product(
Let's pick up the
title attribute to start with. Let's just start with a custom presence validation.
2. Directory's Creation
This step is super simple. Before creating a separate class for the Product validation, it's necessary to add this class to a directory.
Any folders in app/ will be autoloaded, so you could create app/validators/my_validator.rb and include MyValidator in your model. Rails will autoload that and find it correctly. This is my preferred way of doing things usually.
Anyway, let's continue and go step by step.
Let's create a directory called
It depends on your Rails version, but your app directory would look something like this
ls app assets controllers helpers mailers models validators views
3. Validator's Creation
The third step is to create the responsible class for the validation.
Inside app/validators, create a file called
ls app/validators/ product_validator.rb
4. Implement the class
The fourth step is to create a structure for the
Pay attention, the file is
product_validator.rb and the class must be called
#app/validators/product_validator.rb class ProductValidator < ActiveModel::Validator # Code goes here end
5. Implement the validate method
class ProductValidator < ActiveModel::Validator def validate(record) if record.title.blank? record.errors[:title] << (options[:message] || "can't be blank") end # Add other validations for other attributes here end end
6. Include the new validator class
In our example, let's use the
It's necessary to add
include ActiveModel::Validations module into the Product class. This allows the class to use the validation methods and helpers provided by the
In order to declare our new validation class for the
Product model, we're going to use the following command inside your model
This should be the result so far
#app/models/product.rb class Product < ActiveRecord::Base include ActiveModel::Validations attr_accessible :description, :image_url, :price, :title end
7. Use the new validate method
#app/models/product.rb validates_with ProductValidator
The result should look something like the following:
#app/models/product.rb class Product < ActiveRecord::Base include ActiveModel::Validations attr_accessible :description, :image_url, :price, :title validates_with ProductValidator end
8. Test in the console
product = Product.new product.save!
You might see something like this
0.1ms) begin transaction (0.1ms) rollback transaction ActiveRecord::RecordInvalid: Validation failed: Title can't be blankproduct = Product.new => #<Product id: nil, title: nil, description: nil, image_url: nil, price: nil, created_at: nil, updated_at: nil> product.save! (
Summing up, In Part I, we had a basic introduction to validations.
Part II provided more details and more examples.
In conclusion, using custom validations in separate classes with Ruby on Rails can be a powerful tool for simplifying complex validation rules and promoting code reuse.
By following the steps outlined in this article, you can create your own custom validators and apply them to your Rails models with ease. Whether you are a seasoned Rails developer or just starting out, custom validators can help you build more robust and maintainable applications.
Way to go, guys. You did a great job. You can definitely celebrate!
That's all for today. Thanks for reading this article.
I hope this article helped you. Let me know if you have any questions.
Your thoughts, suggestions and corrections are more than welcome.
By the way, feel free to drop your suggestions on new blog articles.
Hope to see you next time.