Form validations in Ruby On Rails Application.

September 2, 2022

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
Enter fullscreen modeExit fullscreen mode

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
Enter fullscreen modeExit fullscreen mode

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
              <p class="error">#{instance_tag&.error_message&.first}</p>


Enter fullscreen modeExit fullscreen mode

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;
Enter fullscreen modeExit fullscreen mode

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 %>
Enter fullscreen modeExit fullscreen mode

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:

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

Source link

Comments 0

Leave a Reply

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