class Product < ApplicationRecord validate :price_must_be_positive def price_must_be_positive errors.add(:price, "must be positive") if price && price <= 0 end end product = Product.new(price: -5) valid = product.valid? saved = product.save
When a custom validation method adds an error to the model's errors, the model becomes invalid. Calling valid? returns false, and save returns false because it does not save invalid records.
class User < ApplicationRecord # Which of these custom validation method definitions is correct? # Option A validate :check_name def check_name errors.add(:name, "can't be blank") if name.blank? end # Option B validate check_name def check_name errors.add(:name, "can't be blank") if name.blank? end # Option C validates :check_name def check_name errors.add(:name, "can't be blank") if name.blank? end # Option D validate :check_name() def check_name errors.add(:name, "can't be blank") if name.blank? end end
The validate method expects a symbol naming the custom validation method without parentheses. Option A uses validate :check_name which is correct. Option A misses the colon, Option A uses validates which is for attribute validations, and Option A uses parentheses which is invalid syntax.
class Order < ApplicationRecord validate :check_total def check_total if total < 0 errors[:total] << "cannot be negative" end end end order = Order.new(total: -10) order.save order.errors.full_messages
Directly pushing to errors[:total] bypasses some of Rails' error handling logic such as internationalization support and options. The recommended and proper way is to use errors.add(:total, "cannot be negative").
class Event < ApplicationRecord validate :start_date_cannot_be_in_past def start_date_cannot_be_in_past if start_date && start_date < Date.today errors.add(:start_date, "can't be in the past") end end end event = Event.new(start_date: Date.today - 1) event.valid? event.errors.full_messages
The custom validation adds an error message if the start_date is before today. Since the date is yesterday, the error message is added and returned by errors.full_messages.
validates_presence_of or validates_numericality_of?Custom validation methods allow developers to write any logic needed for validation, especially when conditions or complex rules are required that built-in validators do not support.