Allyl Isocyanate
Allyl Isocyanate

Reputation: 13626

Adding custom validations to ActiveRecord module via extend?

I'm trying to move my validations to a module. I want to extend an existing object an aribtrary set of validators, but I'm struggling to figure out how to get them to execute. Any ideas?

Active Record Object

class Test < ActiveRecord::Base
  has_many :resources
end

Validator

module TestValidator
  extend ActiveSupport::Concern

  included do
    validates_associated :resources
  end
end

Console

t = Test.new
t.extend TestValidator
t.valid?
# true ... should be false

Upvotes: 3

Views: 3936

Answers (1)

Ben Zhang
Ben Zhang

Reputation: 1281

I hope this can help

6.1 Custom Validators Custom validators are classes that extend ActiveModel::Validator. These classes must implement a validate method which takes a record as an argument and performs the validation on it. The custom validator is called using the validates_with method.

class MyValidator < ActiveModel::Validator
  def validate(record)
    unless record.name.starts_with? 'X'
      record.errors[:name] << 'Need a name starting with X please!'
    end
  end
end



class Person
  include ActiveModel::Validations
  validates_with MyValidator
end

The easiest way to add custom validators for validating individual attributes is with the convenient ActiveModel::EachValidator. In this case, the custom validator class must implement a validate_each method which takes three arguments: record, attribute and value which correspond to the instance, the attribute to be validated and the value of the attribute in the passed instance.

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

class Person < ActiveRecord::Base
  validates :email, :presence => true, :email => true
end

As shown in the example, you can also combine standard validations with your own custom validators.

https://guides.rubyonrails.org/active_record_validations.html#custom-validators

Upvotes: 5

Related Questions