Goal
You’ll be able to add model validations, and understand precisely when validations actually run — a detail that explains a common source of confusion for beginners.
Learn
Validations ensure a model’s data meets certain rules before it’s saved to the database:
class Product < ApplicationRecord
validates :name, presence: true
validates :price, numericality: { greater_than: 0 }
validates :sku, uniqueness: true
end Attempting to save an invalid record doesn’t raise an error by default — save simply returns false, and the record isn’t persisted to the database:
product = Product.new(name: "", price: -5) product.save # returns false, NOT saved product.errors.full_messages # ["Name can't be blank", "Price must be greater than 0"]
Here’s the genuinely important detail about timing: validations run specifically when you call save, create, or update — NOT when you simply build an object with .new or directly assign an attribute. This means you can create an “invalid” object in memory temporarily (useful for building up a form, for example) without validation errors occurring until you actually attempt to persist it.
If you genuinely need save to raise an exception on failure rather than just returning false, save! (with a bang) does exactly that — raising ActiveRecord::RecordInvalid instead of silently returning false, useful when an invalid save should genuinely be treated as an unexpected error condition in that specific context.
Decision Task
You write product = Product.new(name: "") where name has a presence validation. Before reading on: does this line raise a validation error immediately?
Show Answer
No — validations don’t run when simply building an object with .new; they run specifically when you call save, create, or update. The invalid product object exists fine in memory at this point; the validation error would only actually occur (product.save returning false) once you attempt to persist it to the database.
Common Mistake
Assuming validation errors happen immediately when an invalid attribute is assigned, rather than understanding they specifically run at save/create/update time. This misunderstanding can cause confusion when debugging — checking for errors right after .new (before ever calling save) will show no errors at all, since validation genuinely hasn’t run yet at that point.
Practice Questions
1. Write a validation ensuring a Book model’s title attribute is present.
Show Answer
validates :title, presence: true
2. What does save return if a record fails validation, by default (without the bang)?
Show Answer
false — the record is not persisted, but no exception is raised.
3. What method call actually triggers validations to run: .new, or .save?
Show Answer
.save (or .create, or .update) — .new alone does not trigger validation.
4. What does save! do differently from save when validation fails?
Show Answer
It raises an ActiveRecord::RecordInvalid exception instead of just returning false, treating the invalid save as an actual error condition to be handled.
5. How would you check the specific validation error messages after a failed save?
Show Answer
product.errors.full_messages
Try It Yourself
Without looking back, write a Product model validation ensuring the stock attribute is a number greater than or equal to 0.
Show Answer
validates :stock, numericality: { greater_than_or_equal_to: 0 }
Quick Check
1. What do validations ensure?
Show Answer
That a model’s data meets certain rules before being saved to the database.
2. What does save return by default if validation fails?
Show Answer
false, without raising an exception.
3. When do validations actually run: at .new time, or at .save time?
Show Answer
At .save (or .create/.update) time, not at .new time.
4. What does save! do differently from save on validation failure?
Show Answer
It raises an exception (ActiveRecord::RecordInvalid) instead of returning false.
5. How do you check specific validation error messages on a model instance?
Show Answer
model_instance.errors.full_messages