Form validations in Ruby On Rails Application.


In this article, we will learn how to manage server-side and client-side form validations according to our requirements and how we manage this at the application level.

Recently I have worked on form-validation systems in a couple of modern Rails apps, and I learned a few things along the way I would like to share.

Example and source code

I prepared a demo project here. It’s a Rails 5.2 application with a scaffold generated for managing users. A user has 2 attributes: name and email. The validations are:

  • Both name and email are required: to exercise client-side validations.

  • The email has to be unique, to exercise server-side validations.

Server-side validations with Rails

I love Rails validations. They are a powerful mechanism to capture your domain model validation rules, which are essential components of any app. For our example, we can capture the model constraints with something like this:

class User < ApplicationRecord
  validates :name, :email, presence: true
  validates :email, uniqueness: true

A common Rails pattern for dealing with form errors is re-rendering the form with the invalid model carrying the errors to inform about them:

class UsersController < ApplicationController
  def create
    @user =
      redirect_to @user, notice: 'User was successfully created.'
      render :new

  def update
    if @user.update(user_params)
      redirect_to @user, notice: 'User was successfully updated.'
      render :edit

If you are going to use this approach there is a problem with it how we can show errors next to fields.

For dealing with the problem, you can customize ActionView::Base.field_error_proc which is a block of code that Rails uses to render fields with errors. By default, it will wrap them in a div.field_with_errors tag. You can configure it to render the same structure as client-side validations. In our example:

  1. Invalid fields are marked with a .invalid class

  2. Information about the error is shown in a p.error element next to the invalid field.

# Place this code in a initializer. 
# E.g: config/initializers/form_errors.rb
ActionView::Base.field_error_proc = do |html_tag, instance_tag|
  fragment = Nokogiri::HTML.fragment(html_tag)
  field ='input,select,textarea')

  html = if field
           field['class'] = "#{field['class']} invalid"
           html = <<-HTML


HTML html else html_tag end html.html_safe end

CSS — You can customize it according to your requirements.

# app/assets/stylesheets/application.css

.field p{
  margin-top: 0;

  color: red;

  border: 1px solid red;

The new form validations look like this:

Image description

we will have a form that validates duplicated emails consistently with our system.

Image description

What I love about this approach is that you don’t need to do any extra work to show model errors in your forms. Just add model validations.

Client side validations with HTML 5

Form validations are captured in the HTML markup. You can read a nice reference here. For our purposes, we will modify the generated scaffold form to use them:

<%= form.text_field :name, required: true %>
<%= form.email_field :email, required: true %>

With this in place, the browser won’t allow submitting invalid data, and it will show an error message based on the kind of validation.

Image description

This works but you probably won’t love how it looks, and you can’t style it at all.

I like server-side validation because it is not dependent on the client machine or browser or OS.


The discussed approach works great because, with a little bit of infrastructure in place, it lets you express your form validations very succinctly while being robust and comprehensive:

  • Use HTML5 form validations when they cover the validation you need

  • Use model validations in your server. This is something you want to do nevertheless.

If this guide has been helpful to you and your team please share it with others!

Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post

What are Arrays? – Part IV

Next Post

4 ways to personalize your marketing messaging and boost engagement

Related Posts