aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib
diff options
context:
space:
mode:
authorPrem Sichanugrist <s@sikachu.com>2010-02-18 22:28:48 +0700
committerJosé Valim <jose.valim@gmail.com>2010-02-21 12:37:46 +0100
commit8f97e9d19abf02b33c5f7c0c1f1d5daf13e28893 (patch)
tree3858a21a27d5c83e67b28722a3b7b9d62c16efa9 /activemodel/lib
parent250c8092461f5e6bf62751b313f6605a37fd1b2b (diff)
downloadrails-8f97e9d19abf02b33c5f7c0c1f1d5daf13e28893.tar.gz
rails-8f97e9d19abf02b33c5f7c0c1f1d5daf13e28893.tar.bz2
rails-8f97e9d19abf02b33c5f7c0c1f1d5daf13e28893.zip
Add validators reflection so you can do 'Person.validators' and 'Person.validators_on(:name)'.
Signed-off-by: José Valim <jose.valim@gmail.com>
Diffstat (limited to 'activemodel/lib')
-rw-r--r--activemodel/lib/active_model/validations.rb21
-rw-r--r--activemodel/lib/active_model/validations/with.rb9
-rw-r--r--activemodel/lib/active_model/validator.rb18
3 files changed, 45 insertions, 3 deletions
diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb
index 03733a9c89..7f6748a660 100644
--- a/activemodel/lib/active_model/validations.rb
+++ b/activemodel/lib/active_model/validations.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/array/extract_options'
+require 'active_support/core_ext/class/attribute'
require 'active_support/core_ext/hash/keys'
require 'active_model/errors'
@@ -45,6 +46,9 @@ module ActiveModel
included do
extend ActiveModel::Translation
define_callbacks :validate, :scope => :name
+
+ class_attribute :_validators
+ self._validators = Hash.new { |h,k| h[k] = [] }
end
module ClassMethods
@@ -117,9 +121,20 @@ module ActiveModel
end
set_callback(:validate, *args, &block)
end
-
- private
-
+
+ # List all validators that being used to validate the model using +validates_with+
+ # method.
+ def validators
+ _validators.values.flatten.uniq
+ end
+
+ # List all validators that being used to validate a specific attribute.
+ def validators_on(attribute)
+ _validators[attribute.to_sym]
+ end
+
+ private
+
def _merge_attributes(attr_names)
options = attr_names.extract_options!
options.merge(:attributes => attr_names)
diff --git a/activemodel/lib/active_model/validations/with.rb b/activemodel/lib/active_model/validations/with.rb
index db563876af..83d3ea80d6 100644
--- a/activemodel/lib/active_model/validations/with.rb
+++ b/activemodel/lib/active_model/validations/with.rb
@@ -62,6 +62,15 @@ module ActiveModel
args.each do |klass|
validator = klass.new(options, &block)
validator.setup(self) if validator.respond_to?(:setup)
+
+ if validator.respond_to?(:attributes) && !validator.attributes.empty?
+ validator.attributes.each do |attribute|
+ _validators[attribute.to_sym] << validator
+ end
+ else
+ _validators[nil] << validator
+ end
+
validate(validator, options)
end
end
diff --git a/activemodel/lib/active_model/validator.rb b/activemodel/lib/active_model/validator.rb
index ad9729de00..b61f0cb266 100644
--- a/activemodel/lib/active_model/validator.rb
+++ b/activemodel/lib/active_model/validator.rb
@@ -1,3 +1,5 @@
+require "active_support/core_ext/module/anonymous"
+
module ActiveModel #:nodoc:
# A simple base class that can be used along with
# +ActiveModel::Validations::ClassMethods.validates_with+
@@ -88,11 +90,27 @@ module ActiveModel #:nodoc:
class Validator
attr_reader :options
+ # Returns the kind of the validator.
+ #
+ # == Examples
+ #
+ # PresenceValidator.kind #=> :presence
+ # UniquenessValidator.kind #=> :uniqueness
+ #
+ def self.kind
+ @kind ||= name.split('::').last.underscore.sub(/_validator$/, '').to_sym unless anonymous?
+ end
+
# Accepts options that will be made availible through the +options+ reader.
def initialize(options)
@options = options
end
+ # Return the kind for this validator.
+ def kind
+ self.class.kind
+ end
+
# Override this method in subclasses with validation logic, adding errors
# to the records +errors+ array where necessary.
def validate(record)