Skip to content

Instantly share code, notes, and snippets.

@bbozo
Last active December 14, 2015 01:29
Show Gist options
  • Save bbozo/5006180 to your computer and use it in GitHub Desktop.
Save bbozo/5006180 to your computer and use it in GitHub Desktop.
class ExampleController < ApplicationController
def some_post_action
@some_model = SomeModel.some_factory_method(params).
validate(:make_one_particular_and_unique_thingy_go_red_and_stop_save)
...
end
end
# Instance validators patch. If model instance defines an instance_validators
# method, it will be invoked during validation
module ActiveRecord::InstanceValidators
def valid?(*args, &block)
output = super(*args, &block)
instance_validators
errors.empty? && output
end
# [14] pry(main)> m = Member.last
# [15] pry(main)> def m.kme; errors.add(:base, 'kme'); end
# [16] pry(main)> m.validate(:kme){ |m| m.errors.add(:base, 'foo')}
# [17] pry(main)> m.valid?
# => false
# [21] pry(main)> m.errors.messages
# => {:base=>["kme", "foo"]}
def validate(*args, &block)
args.each do |method|
__instance_validator_callbacks << lambda{ self.send(method) }
end
__instance_validator_callbacks << block if block
self # allow chaining
end
private
def instance_validators
__instance_validator_callbacks.each do |callback|
args = [self][0...callback.arity]
callback.call(*args)
end
__instance_validator_callbacks
end
def __instance_validator_callbacks
@__instance_validator_callbacks ||= []
end
end
ActiveRecord::Base.send :include, ActiveRecord::InstanceValidators
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment