Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails ActiveRecord: validate single attribute

Is there any way I can validate a single attribute in Rails?

Something like:

ac_object.valid?(attribute_name) 
like image 274
Nikita Fedyashev Avatar asked Jan 26 '11 12:01

Nikita Fedyashev


People also ask

What is the difference between validate and validates in rails?

So remember folks, validates is for Rails validators (and custom validator classes ending with Validator if that's what you're into), and validate is for your custom validator methods.

How do I bypass validation?

A very common way to skip validation is by keeping the value for immediate attribute as 'true' for the UIComponents. Immediate attribute allow processing of components to move up to the Apply Request Values phase of the lifecycle. scenario: While canceling a specific action, system should not perform the validation.

How does validation work in Rails?

Rails validation defines valid states for each of your Active Record model classes. They are used to ensure that only valid details are entered into your database. Rails make it easy to add validations to your model classes and allows you to create your own validation methods as well.


2 Answers

Sometimes there are validations that are quite expensive (e.g. validations that need to perform database queries). In that case you need to avoid using valid? because it simply does a lot more than you need.

There is an alternative solution. You can use the validators_on method of ActiveModel::Validations.

validators_on(*attributes) public

List all validators that are being used to validate a specific attribute.

according to which you can manually validate for the attributes you want

e.g. we only want to validate the title of Post:

class Post < ActiveRecord::Base    validates :body, caps_off: true    validates :body, no_swearing: true   validates :body, spell_check_ok: true    validates presence_of: :title   validates length_of: :title, minimum: 30 end 

Where no_swearing and spell_check_ok are complex methods that are extremely expensive.

We can do the following:

def validate_title(a_title)   Post.validators_on(:title).each do |validator|     validator.validate_each(self, :title, a_title)   end end 

which will validate only the title attribute without invoking any other validations.

p = Post.new p.validate_title("") p.errors.messages #=> {:title => ["title can not be empty"] 

note

I am not completely confident that we are supposed to use validators_on safely so I would consider handling an exception in a sane way in validates_title.

like image 96
xlembouras Avatar answered Sep 21 '22 12:09

xlembouras


You can implement your own method in your model. Something like this

def valid_attribute?(attribute_name)   self.valid?   self.errors[attribute_name].blank? end 

Or add it to ActiveRecord::Base

like image 43
egze Avatar answered Sep 21 '22 12:09

egze