Skipping Validations in Ruby On Rails

This article will show you how to conditionally skip validations in your Rails App.


Published on:August 2, 2014
Rails Version 3.0 and Up
Required Dependencies None

Introduction

The Ruby on Rails validations feature is a lifesaver when it comes to validating data. However, what happens when you want to skip validations and allow invalid data anyway? This short tutorial will show you how to both skip all validations as well as individual validations.

Skip All Validations

Fortunately, skipping all validations on create is easy. For new records simply modify your create method to look like the following:


def create
  @product = Product.new(product_params)
   if @product.save(validate: false)
    redirect_to products_path, notice: "#{@product.name} has been created."
  else
    render 'new'
  end
end

Notice we simply pass a parameter to the save method of validate: false. This will tell Rails to disable all the validations during the save.

Disabling validations during an update is less straightforward, but still just as easy. Simple do:


def update
  @product = Product.find(params[:id])
  @product.attributes = product_params
    
  if @product.save(validate: false)
    redirect_to products_path, notice: "The product \"#{@product.name}\" has been updated. "
  else
    render 'edit'
  end
end

The Rails update_attributes method does not include support for disabling validations during update, so instead we assign the attributes to the product manually and then call save while passing validate: false.

Skipping Individual Validations

Skipping individual validations requires a bit more work. First we need to create a property on our model called something like skip_name_validation:


attr_accessor :skip_name_validation, :skip_price_validation

Next we will tell Rails to check and see if that property is set to true:


validates :name, presence: true, uniqueness: true, unless: :skip_name_validation
validates :price, presence: true, numericality: { greater_than: 0 }, unless: :skip_price_validation

Finally we will set the property to true any time we want to skip validations. For example:


def create
   @product = Product.new(product_params)
   @product.skip_name_validation = true
   if @product.save
    redirect_to products_path, notice: "#{@product.name} has been created."
  else
    render 'new'
  end
end

def update
  @product = Product.find(params[:id])
  @product.attributes = product_params

  @product.skip_price_validation = true
    
  if @product.save
    redirect_to products_path, notice: "The product \"#{@product.name}\" has been updated. "
  else
    render 'edit'
  end
end

Above you will see that for the create method we skip name validation; and for the update method we skip price validation. A complete listing of the model is shown below.


class Product < ActiveRecord::Base
  validates :name, presence: true, uniqueness: true, unless: :skip_name_validation
  validates :price, presence: true, numericality: { greater_than: 0 }, unless: :skip_price_validation

  attr_accessor :skip_name_validation, :skip_price_validation
end

That's it, thanks for reading!