Reputation: 13626
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
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