Working with Custom Validations in Rails

This article will discuss a concept known as Custom Validations in Rails Active Record. There are two types of custom validations; Custom Validators and Custom Methods.

Here’s a bit of setup before tackling each type individually:

1
2
3
rails new custom-validations
rails generate model Article title body:text
rails db:create db:migrate

Start with Custom Validator. In app/models/concerns, create a file named title_validator.rb and put the following content in it:

1
2
3
4
5
6
7
8
9
# app/models/concerns/title_validator.rb

class TitleValidator < ActiveModel::Validator
 def validate(record)
   unless record.title.include? 'Rails'
     record.errors[:title] << 'We only publish articles written on Rails!'
   end
 end
end

Include it in the app/models/article.rb.

1
2
3
4
5
6
# app/models/article.rb

class Article < ApplicationRecord
 include ActiveModel::Validations
 validates_with TitleValidator
end

Now test the validator.

1
2
3
4
5
6
7
8
9
10
rails console
article = Article.create(title: "Uploading Images in Laravel", body: "This aticle will discuss how to upload images in Laravel.....")
article.valid?
=> false 
article.errors
=> #<ActiveModel::Errors:0x00007fe54e236b40 @base=#<Article id: nil, title: "Uploading Images in Laravel", body: "This aticle will discuss how to upload images in L...", created_at: nil, updated_at: nil>, @messages={:title=>["We only publish articles written on Rails!"]}, @details={}> 

article = Article.create(title: "Uploading Images in Rails", body: "This article will discuss how to upload images in Rails.....")
article.valid?
=> true 

Now onto Custom Methods.

1
2
3
4
5
6
7
8
9
class Article < ApplicationRecord
 validate :title_include_rails

 def title_include_rails
   unless title.include? 'Rails'
     errors.add(:title, 'We only publish articles written on Rails!')
   end
 end
end

Test the implementation:

1
2
3
4
5
6
7
8
9
article = Article.create(title: "Uploading Images in Laravel", body: "This aticle will discuss how to upload images in Laravel.....")
article.valid?
=> false 
article.errors
=> #<ActiveModel::Errors:0x00007fe54aaf0960 @base=#<Article id: nil, title: "Uploading Images in Laravel", body: "This aticle will discuss how to upload images in L...", created_at: nil, updated_at: nil>, @messages={:title=>["We only publish articles written on Rails!"]}, @details={:title=>[{:error=>"We only publish articles written on Rails!"}]}> 

article = Article.create(title: "Uploading Images in Rails", body: "This aticle will discuss how to upload images in Rails.....")
article.valid?
=> true 

Now you’ve learned how to implement custom validations in Ruby on Rails. Happy validating!