Skip to content

Instantly share code, notes, and snippets.

@datenimperator
Created September 26, 2011 09:35
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 datenimperator/1241937 to your computer and use it in GitHub Desktop.
Save datenimperator/1241937 to your computer and use it in GitHub Desktop.
Create instance-based validation
require 'rubygems'
gem 'activemodel', '3.0.10'
require 'active_model'
class ChildValidator < ActiveModel::EachValidator
def validate_each(object, attribute, child)
klass = "#{object.process}_child_validator".camelize.constantize rescue nil
child.validates_with klass unless klass.nil?
unless child.errors.empty?
object.errors[attribute] << child.errors.full_messages
end
end
end
class ClassicChildValidator < ActiveModel::Validator
def validate(child)
child.validates_presence_of :city
end
end
class FvkChildValidator < ActiveModel::Validator
def validate(child)
child.validates_presence_of :name
end
end
class A
include ActiveModel::Validations
attr_accessor :child, :process
def initialize
@process = 'classic'
end
validates :child, :child=>true
validates_inclusion_of :process, :in=>%w{classic fvk fdb}
end
class ChildOfA
include ActiveModel::Validations
attr_accessor :name, :city
end
a = A.new.tap{ |a| a.process = 'classic' }
a.child = ChildOfA.new.tap { |c| c.name = "Hubi" }
puts a.valid? ? "Valid" : a.errors.full_messages.join(', ')
b = A.new.tap{ |a| a.process = 'fvk' }
b.child = ChildOfA.new.tap { |c| c.city = "Aachen" }
puts b.valid? ? "Valid" : b.errors.full_messages.join(', ')
c = A.new.tap{ |a| a.process = 'invalid_process' }
c.child = ChildOfA.new
puts c.valid? ? "Valid" : c.errors.full_messages.join(', ')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment