When we develop a new feature, it's common to add a new column that needs some validations in the model. So, we might write something like this:
class Book < ApplicationRecord
#...
validates :barcode, presence: true
end
To increase the test coverage, adding the test example is necessary:
RSpec.describe Book, type: :model do
#...
it { is_expected.to validate_presence_of(:barcode) }
end
Everything seems to make sense. All the test examples have passed.
However, something wrong happened after deploying to the production. Rollbar showed warnings that were related to this validation. Some Book records failed to update.
At that time, I suddenly realized I need to think more about 'adding a new validation'.
How to avoid the same situation
The first thing is to ask:
After adding this new validation, can old records pass this new validation when they need updating something?
If the answer is no, that means there are two things we need to think about:
When does this validation need executing? Whenever a record is updated? Or, the validation can be executed only when the column value to an old record is different from before?
What if the new column has to be
presence: true
? My opinion is that we only validate the new record. Because neither should we ask users to update the value themselves, nor inserting the value for them.
class Book < ApplicationRecord
#...
validates :barcode, presence: true, if: :new_record?
end
After adding the validation, we should add the test examples to make sure the timing of the validation execution is as we expect.
Thanks for this experience to remind me:
Even though adding a validation is a simple thing, it's important to estimate if it will cause side effects.