validates_method_of
I personally was looking for a way to validate a specific object method in a model.
In my case I would for exemple to allow only an admin or owner to post an article.
For this I made an extention to the active record ’s validations class methods to allow me to do this simply and with flexibility.
validates_method_of.rb: (updated after Jean-François comments)
module ActiveRecord
module Validations
module ClassMethods
# Validates whether the value of the specified object method is correct from matching
# one of the accepted values provided or if different than the excepted one
#
# class Article < ActiveRecord::Base
# validates_method_of :user, :method => 'role', :only => %w( owner admin )
# end
#
# Configuration options:
# * <tt>method</tt> - The method that will be validate
# * <tt>message</tt> - A custom error message (default is: "not authorized")
# * <tt>only</tt> - An enumerable object of items that the value should be part of
# * <tt>except</tt> - An enumerable object of items that the value shouldn't be part of
def validates_method_of(*attr_names)
configuration = { :message => 'not authorized', :on => :save }
configuration.update(attr_names.pop) if attr_names.last.is_a?(Hash)
if configuration[:only]
enum = configuration[:only]
validates_each(attr_names, configuration) do |record, attr_name, value|
if !value.blank?
method = value.send(configuration[:method].to_s)
record.errors.add(attr_name, configuration[:message]) if !enum.include?(method)
end
end
else
enum = configuration[:except]
validates_each(attr_names, configuration) do |record, attr_name, value|
if !value.blank?
method = value.send(configuration[:method].to_s)
record.errors.add(attr_name, configuration[:message]) if enum.include?(method)
end
end
end
end
end
end
end
I personally put this file in my lib directory and loaded it from config/environment.rb like this:
require 'validates_method_of'

Web application developer born in summer '83, I made my company