0
0
RailsHow-ToBeginner · 3 min read

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_name tells Rails to run your custom method when validating.
  • def method_name defines 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 validates instead of validate for custom methods (they are different).
  • Not handling nil values 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_name to run your custom validation method.
  • Inside the method, add errors with errors.add(:attribute, "message").
  • Always handle nil values safely to avoid exceptions.
  • Test validations in Rails console with valid? and errors.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).