3
votes

I am not sure if I understand totally active record validation role.

Of course, if a user inputs data (like an email or a country), I can and should validate its existence, its uniqueness or its inclusion in a list of countries

But for example, if I have methods in the backend that change an attribute page_clicked or click_date or even the column update_at, that I "control" i.e 'is not generated by a user's input', should I use active record validations ?

I'm asking this because on a very 'hot database' (need speed for millions of frequent updates), I wonder if checking on each update that updated_at is a datetime, and that if a clicked column is true/false and nothing esle is really necessary as the user is not the one inputting/controlling these data but I am through Rails custom methods I wrote

Thanks

3

3 Answers

3
votes

I don't think there is a general satisfying answer to your question. It's up to you to enforce validation or not.

Remember that you don't have to use ActiveRecord for validation, you can also use your DBMS to ensure that:

  • a value will never be NULL (one of the most annoying errors)
  • a value has the correct TYPE
  • a FOREIGN KEY always points to an existing row in another table
  • and depending on your DBMS, a lot more is possible

If you need high INSERT speed and want to go with raw SQL INSERTS, putting some validation in your database can prevent nasty application errors later.

1
votes

Validations should guard your database and its job should be to stop saving the records that are considered invalid by your application.

There is no hard rule on what is valid record you have to decide it your self by adding the validations. If the record wont pass the validation step it is simply not going to be saved to the database.

From Active Record Callbacks:

3.1 Creating an Object
before_validation
after_validation
before_save
around_save
before_create
around_create
after_create
after_save
after_commit/after_rollback

3.2 Updating an Object
before_validation
after_validation
before_save
around_save
before_update
around_update
after_update
after_save
after_commit/after_rollback

You can see that validation hooks run at the beginning of the object life cycle.

So in your case instead of asking your self a question:

Should I use active record validations if the record is not generated by a user's input.

You should ask your self:

Is this record invalid without page_clicked or click_date(aka them being nil)

UPDATE

If you consider record to be invalid but worrying about speed problems with running validations I would do the validations to make sure that all the records in the database are valid and try to find the way to optimise the speed somewhere else. Plus not 100% sure but time spend on saving invalid records and filtering them later on will be probably much longer then validating in the first place.

0
votes

When performance is really a priority and that I am sure that we developers / the server are the only ones who can manipulate specific attributes of a Model, I will

  1. Make sure that I create a separate method / wrapper method for this specific action.

  2. In this specific method, I call .save (validate: false) instead of the usual .save

  3. I still write validations for the said attributes for developers' reference to prevent future development errors, and in case a new developer comes in and accidentally save an invalid record, precisely just because there's no validation to safeguard it.

  4. Or, I will use .update_column instead of .save (validate: false) to perform a direct DB call, skipping Model validations and callbacks (If you also do not want callbacks to be called).

Note that .update_column is different from .update.