asalgan
asalgan

Reputation: 326

Rails accessing a shared custom validation in a module within a model

I'm trying to figure out how to create a shared custom validation that I can use across my models that I've placed within a lib/validations.rb folder.

module Validations
  extend ActiveSupport::Concern

  # included do


  def email_format_validation
    if self.email.present?
      if !validates_format_of :email, with: email_regex
        self.errors.add(:email, "doesn't exist")
      end
    end
  end


  def email_regex
    /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
  end
end

So in my model, this allows me to do:

validate :email_format_validation

In other models, I'm trying to just call email_regex:

validate :user_email, with: email_regex

which produces the following error:

undefined local variable or method `email_regex' for #<Class....>

I've tried using include Validations, extend Validations, require 'validations', etc. in my model with no luck. I've also tried placing the module methods within a class << self, using the included do block, setting the methods as self.email_regex and calling Validations.email_regex and yet nothing seems to work.

Upvotes: 2

Views: 2498

Answers (3)

ggsp
ggsp

Reputation: 452

As of Rails 3, you may also use validates_with:

class EmailValidator < ActiveModel::Validator
  def validate(record)
    if record.email.present?
      if !email_regex.match?(record.email)
        record.errors.add(:email, "is invalid")
      end
    end
  end

  private

  def email_regex
    /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
  end
end

class User < ApplicationRecord
  validates_with EmailValidator
end

This allows you to e.g. easily make the field name dynamic.

Upvotes: 1

Nandhini
Nandhini

Reputation: 665

I tried the following and it worked for me:

Created validations.rb in models/concerns

module Validations
  extend ActiveSupport::Concern

  def email_format_validation
    if self.email.present?
      if !validates_format_of :email, with: email_regex
        self.errors.add(:email, "doesn't exist")
      end
    end
  end


  def email_regex
    /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
  end
end

In the model:

include Validations

class User < ApplicationRecord
  validate :email_format_validation
  validates :user_email, with: :email_regex
end

user_email is the field name

Upvotes: 5

grangersg1993
grangersg1993

Reputation: 1

Have you tried using require_relative Validations

Upvotes: 0

Related Questions