Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: calling standard validations from a custom validator

Is there a way to call standard Rails validators from within a custom validator?

I have a combination of OAuth/email signup/sign in and I want to be able to call certain validators on each method of authentication. For instance, I want to be able to call validates_uniqueness_of :email if the user signs up through email and then call a single validator, for instance validates_with UserValidator.

If there isn't a way to do this I'm just going to use state tracking and a series of :if validations.

like image 233
Tyler Morgan Avatar asked Oct 16 '25 03:10

Tyler Morgan


2 Answers

I believe there's no way to call other validators from custom one, this also may possibly cause circular dependency which is dangerous.

You have to go with conditional validations, but keep in mind that you can scope them like this (taken from Rails Guides)

with_options if: :is_admin? do |admin|
  admin.validates :password, length: { minimum: 10 }
  admin.validates :email, presence: true
end
like image 197
Mike Szyndel Avatar answered Oct 18 '25 16:10

Mike Szyndel


If your goal is to call some combination of custom and standard rails validators you can do that with the validates method provided by ActiveModel::Validations

For example, you've created a custom Email Validator:

class EmailValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    record.errors.add attribute, (options[:message] || "is not an email") unless
      value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
  end
end

And you want to include it in your Person class. You can do like so:

class Person < ApplicationRecord
  attr_accessor :email

  validates :email, presence: true, email: true
end

which will call your custom validator, and the PresenceValidator. All examples here are taken from the docs ActiveModel::Validations::Validates

like image 37
Kyle Snow Schwartz Avatar answered Oct 18 '25 17:10

Kyle Snow Schwartz