It seems that validates_uniqueness_of :some_field will run on a "save" even if the some_field attribute has not changed (if other fields have changed). This seems wasteful, since each validates_uniqueness_of will require a database call. I know I can pass a Proc to validates_uniqueness_of to check whether some_field has changed, and I am considering going through all the validations and doing that wherever possible. What I am wondering is:
1) Is that what people interested in performance generally do with their validations?
2) Why is it not validates_uniqueness_of's default behavior to check whether the attribute has changed first?
3) Are there good reasons for running such validations on attributes that haven't changed?
I am using Rails 2.3 (for the moment-- we are working on upgrading). I don't know this is the same situation in Rails 3.
If any validations fail, the object will be marked as invalid and Active Record will not perform the INSERT or UPDATE operation. This helps to avoid storing an invalid object in the database. You can choose to have specific validations run when an object is created, saved, or updated.
In Rails, validations are used in order to ensure valid data is passed into the database. Validations can be used, for example, to make sure a user inputs their name into a name field or a username is unique.
Validations are used to ensure that only valid data is saved into your database. For example, it may be important to your application to ensure that every user provides a valid email address and mailing address. Model-level validations are the best way to ensure that only valid data is saved into your database.
So, save! won't just return true or false but only true on success and raise an excpetion if it fails. The purpose of this distinction is that with save! , you are able to catch errors in your controller using the standard ruby facilities for doing so, while save enables you to do the same using standard if-clauses.
What if someone changed the value in the database directly?
What if some other (non rails app) app also accesses the database?
In all above scenarios you will still want that your data be valid, so that your rails application behaves as expected. In case the data was tampered with (by the other app, or in database directly), your rails app throws an error because it doesn't expect that data.
Having said that, it is the default behaviour. The default behaviour is generally more restrictive, in order to maintain data validity and minimise scope of errors, omissions, and occasional slips. In case you are worried about performance in your case, maybe your object is being updated very frequently, and you have a lengthy custom validation on a field that isn't being updated that frequently, and you don't want to run that validation each time, then it makes perfect sense to customize the default behaviour as you have described in the question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With