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!