When building applications we try to make sure the data our users are submitting is reliable and useful.
Ensuring valid data is sent before saving any changes to the database is called validation.
Traditionally, HTML5 provides instant validation trough input: type and required tags.
Rails use Active Record Validations to ensure the information in the database is consistent and adds an extra security layer to our deployed
projects.
projects.
While there are a variety of options available within Rails guides, a couple of quick configurations to validate the most common user input can go a long way.
In this quick guide, we will validate a table with name, email, and
password: fields used when a user’s login feature is required
password: fields used when a user’s login feature is required
Let’s get started by creating a new Rails App (or open your existing project) with default database configuration.
$ rails new rails-sampleThe next step is to create a sample table with basic required cells for a user’s login.
$ rails generate scaffold User name:string email:string password:stringdon’t forget to create and migrate your database.
$ rails db:create
$ rails db:migrateyou should have this on app/model/user.rb:
class User < ApplicationRecord
endand your database schema (./bd/schema.rb) should be this.
create_table “users”, force: :cascade do |t|
t.string “name”
t.string “email”
t.string “password”
t.datetime “created_at”, precision: 6, null: false
t.datetime “updated_at”, precision: 6, null: false
endnow we can start adding the essential validations
Presence
We use the presence validator whenever we need the input to exist. In this example we need all our fields to be present in order to validate the entry:
class User < ApplicationRecord
validates :name, presence: true
validates :email, presence: true
validates :password, presence: true
endnow, let’s use rails console sandbox to be sure our validators are working:
$ rails console --sandbox
> user1 = User.create(email: "email1", password: "sample1")
=> #<User id: nil, name: nil, email: "email1", password: [FILTERED], created_at: nil, updated_at: nil>
> user1.valid?
=> falsewe created user1 without any name thus, valid? = false, let's try again
> user = User.create(name: "user1", email: "email1", password: "sample1")
=> #<User id: 1, name: "user1", email: "email1", password: [FILTERED], created_at: "2020-07-08 17:06:32", updated_at: "2020-07-08 17:06:32">
> user.valid?
=> true¡Much better!.
Length
we use the length validator to a 255 maximum to avoid any database overflowing.
class User < ApplicationRecord
validates :name, presence: true, length: { minimum: 3, maximum: 25 }
validates :email, presence: true, length: { minimum: 10, maximum: 255 }
validates :password, presence: true, length: { minimum: 6, maximum: 255 }
endRegex format
for email validation, we use regular expression format like this one:
/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/iWe update our model using this regular expression and format: validator
class User < ApplicationRecord
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i.freeze
validates :name, presence: true, length: { minimum: 3, maximum: 25 }
validates :password, presence: true, length: { minimum: 6, maximum: 255 }
validates :email, presence: true, length: { minimum: 10, maximum: 255 },format: { with: VALID_EMAIL_REGEX }
endUniqueness
We can add a uniqueness validation to avoid any email duplicates disabling case sensitivity:
class User < ApplicationRecord
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i.freeze
validates :name, presence: true, length: { minimum: 3, maximum: 25 }
validates :password, presence: true, length: { minimum: 6, maximum: 255 }
validates :email, presence: true, length: { minimum: 10, maximum: 255 },format: { with: VALID_EMAIL_REGEX },uniqueness: { case_sensitive: false }
endand finally we run rails console to ensure our validations are in order
$ rails console --sandbox
> user = User.create(name: "user1", email: "[email protected]", password: "password")
=> #<User id: 1, name: "user1", email: "[email protected]", password: [FILTERED], created_at: "2020-07-08 17:26:29", updated_at: "2020-07-08 17:26:29">
> user.valid?
=> truethis essential validation process will add an extra filter to ensure data liability in any Rails app.
you can add as many validations as you see fit, check Ruby guides for the complete documentation.