How to Create Custom Validation in Ruby on Rails
In Ruby on Rails, create custom validations by defining a method in your model and using
validate :method_name to call it. Inside the method, add errors with errors.add(:attribute, "message") when validation fails.Syntax
To create a custom validation in Rails, define a method in your model and use validate :method_name to run it during validation. Inside the method, use errors.add(:attribute, "error message") to add validation errors.
validate :method_nametells Rails to run your custom method when validating.def method_namedefines the custom validation logic.errors.add(:attribute, "message")adds an error to the attribute if validation fails.
ruby
class User < ApplicationRecord validate :email_must_be_company_domain def email_must_be_company_domain unless email&.end_with?('@company.com') errors.add(:email, 'must be a company email') end end end
Example
This example shows a User model with a custom validation that checks if the email ends with '@company.com'. If not, it adds an error message to the email attribute.
ruby
class User < ApplicationRecord validate :email_must_be_company_domain def email_must_be_company_domain unless email&.end_with?('@company.com') errors.add(:email, 'must be a company email') end end end # Usage example in Rails console: user = User.new(email: 'test@gmail.com') user.valid? # => false user.errors.full_messages # => ["Email must be a company email"] user2 = User.new(email: 'employee@company.com') user2.valid? # => true user2.errors.full_messages # => []
Output
false
["Email must be a company email"]
true
[]
Common Pitfalls
Common mistakes when creating custom validations include:
- Not calling
validate :method_name, so the method never runs. - Forgetting to add errors with
errors.add, which makes validation always pass. - Using
validatesinstead ofvalidatefor custom methods (they are different). - Not handling
nilvalues safely, causing errors in the validation method.
ruby
class User < ApplicationRecord # Wrong: using validates instead of validate validates :email_must_be_company_domain def email_must_be_company_domain # No errors added, so validation always passes email&.end_with?('@company.com') end end # Correct way: class User < ApplicationRecord validate :email_must_be_company_domain def email_must_be_company_domain unless email&.end_with?('@company.com') errors.add(:email, 'must be a company email') end end end
Quick Reference
Summary tips for custom validations in Rails:
- Use
validate :method_nameto run your custom validation method. - Inside the method, add errors with
errors.add(:attribute, "message"). - Always handle
nilvalues safely to avoid exceptions. - Test validations in Rails console with
valid?anderrors.full_messages.
Key Takeaways
Define a method in your model and use validate :method_name to create custom validations.
Add errors inside the method with errors.add(:attribute, "message") to mark validation failures.
Always handle nil values safely in your validation methods to avoid errors.
Use Rails console to test your validations with valid? and errors.full_messages.
Do not confuse validate (for methods) with validates (for built-in validations).