Skip to content

Instantly share code, notes, and snippets.

@ismasan
Created June 26, 2019 09:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ismasan/0b98fbc0a590be5b44d0f5ee8181c5c8 to your computer and use it in GitHub Desktop.
Save ismasan/0b98fbc0a590be5b44d0f5ee8181c5c8 to your computer and use it in GitHub Desktop.
Declarative AM validations depending on arbitrary attributes
# class Page
# include ValidationsFor
#
# validations_for page_type: 'offer' do
# validates :amount, presence: true
# end
#
# validations_for page_type: 'page' do
# validates :title, presence: true
# end
# end
module ValidationsFor
extend ActiveSupport::Concern
class ValidatorWrapper < SimpleDelegator
include ActiveModel::Validations
def self.model_name
ActiveModel::Name.new(ValidatorWrapper)
end
end
included do
mattr_accessor :_validation_spec
validate do |record|
spec = self._validation_spec || []
spec.each do |(attrs, wrapper)|
if attrs.all?{ |k, v| record[k] == v }
validator = wrapper.new(record)
if !validator.valid?
validator.errors.each do |k, msg|
record.errors.add(k, msg)
end
end
end
end
end
end
class_methods do
def validations_for(attrs, &block)
wrapper = Class.new(ValidatorWrapper, &block)
self._validation_spec ||= []
self._validation_spec << [attrs, wrapper]
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment