Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controlling the order of rails validations

I have a rails model which has 7 numeric attributes filled in by the user via a form.

I need to validate the presence of each of these attributes which is obviously easy using

validates :attribute1, :presence => true validates :attribute2, :presence => true # and so on through the attributes 

However I also need to run a custom validator which takes a number of the attributes and does some calculations with them. If the result of these calculations is not within a certain range then the model should be declared invalid.

On it's own, this too is easy

validate :calculations_ok?  def calculations_ok?   errors[:base] << "Not within required range" unless within_required_range? end  def within_required_range?   # check the calculations and return true or false here end 

However the problem is that the method "validate" always gets run before the method "validates". This means that if the user leaves one of the required fields blank, rails throws an error when it tries to do a calculation with a blank attribute.

So how can I check the presence of all the required attributes first?

like image 789
David Tuite Avatar asked May 11 '11 14:05

David Tuite


People also ask

How does validate 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.

What is the difference between validate and validates in rails?

validates is used for normal validations presence , length , and the like. validate is used for custom validation methods validate_name_starts_with_a , or whatever crazy method you come up with. These methods are clearly useful and help keep data clean.

Why must you validate data before persisting it?

Data validation (when done properly) ensures that data is clean, usable and accurate. Only validated data should be stored, imported or used and failing to do so can result either in applications failing, inaccurate outcomes (e.g. in the case of training models on poor data) or other potentially catastrophic issues.


1 Answers

I'm not sure it's guaranteed what order these validations get run in, as it might depend on how the attributes hash itself ends up ordered. You may be better off making your validate method more resilient and simply not run if some of the required data is missing. For example:

def within_required_range?   return if ([ a, b, c, d ].any?(&:blank?))    # ... end 

This will bail out if any of the variables a through d are blank, which includes nil, empty arrays or strings, and so forth.

like image 148
tadman Avatar answered Oct 10 '22 05:10

tadman