valid? method on your presenter instances to determine if they are valid or not.Step one: You define the validation methods in a module.
module Presenters::ValidationsThen, you
def validates_presence_of(*args)
..
end
def validates_format_of(*args)
..
end
end
extend the module to add the class methods to your presenter.class AccountInformationPresenterThis implementation also requires that you define
extend Presenters::Validations
validates_presence_of :username, :password
..
valid? in each presenter class.def valid?When building the second presenter it should be clear that the
self.class.validations.collect do |validation|
unless validation.valid?(self)
self.errors.add(validation.on, validation.message)
end
end.all?
end
end
valid? should be abstracted. This abstraction could result in another module. The new module could be included thus providing valid? as an instance method.Step two: Another common approach is to define the class methods in a ClassMethods module inside the Presenters::Validations module.
module Presenters::ValidationsThis approach, while common in Rails, can generate some dislike. A counter argument is that
module ClassMethods
def validates_presence_of(*args)
..
end
def validates_format_of(*args)
..
end
end
def self.included(base)
base.extend(ClassMethods)
end
def valid?
self.class.validations.collect do |validation|
unless validation.valid?(self)
self.errors.add(validation.on, validation.message)
end
end.all?
end
end
include is designed to add instance methods and using self.included is clever, but provides unexpected behavior. I've found that people who dislike the self.included trick prefer to explicitly use both include and extend.class AccountInformationPresenterWhich approach is better?
include Presenter::Validations
extend Presenter::Validations::ClassMethods
..
end
I tend to prefer explicitness; however, if something is used often enough it can turn from an anti-pattern to an idiom. I'm not sure if that is the case or not here, but I think it might be.