aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/validations.rb
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2008-01-19 02:44:45 +0000
committerJeremy Kemper <jeremy@bitsweat.net>2008-01-19 02:44:45 +0000
commitaae37bb4f7edd6a1820e420a60560369c6064f33 (patch)
tree5642ff690036cac09bc697a0798dd984128d6e73 /activerecord/lib/active_record/validations.rb
parent3ffdfa84fc1f9bebc578fe957646af5f194ca625 (diff)
downloadrails-aae37bb4f7edd6a1820e420a60560369c6064f33.tar.gz
rails-aae37bb4f7edd6a1820e420a60560369c6064f33.tar.bz2
rails-aae37bb4f7edd6a1820e420a60560369c6064f33.zip
Extract ActiveSupport::Callbacks from Active Record, test case setup and teardown, and ActionController::Dispatcher. Closes #10727.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8664 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord/lib/active_record/validations.rb')
-rwxr-xr-xactiverecord/lib/active_record/validations.rb122
1 files changed, 31 insertions, 91 deletions
diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb
index 98dfcece8b..87f128e9a3 100755
--- a/activerecord/lib/active_record/validations.rb
+++ b/activerecord/lib/active_record/validations.rb
@@ -279,6 +279,25 @@ module ActiveRecord
alias_method_chain :save!, :validation
alias_method_chain :update_attribute, :validation_skipping
end
+
+ base.send :include, ActiveSupport::Callbacks
+
+ # TODO: Use helper ActiveSupport::Callbacks#define_callbacks instead
+ %w( validate validate_on_create validate_on_update ).each do |validation_method|
+ base.class_eval <<-"end_eval"
+ def self.#{validation_method}(*methods, &block)
+ options = methods.extract_options!
+ methods << block if block_given?
+ methods.map! { |method| Callback.new(:#{validation_method}, method, options) }
+ existing_methods = read_inheritable_attribute(:#{validation_method}) || []
+ write_inheritable_attribute(:#{validation_method}, existing_methods | methods)
+ end
+
+ def self.#{validation_method}_callback_chain
+ read_inheritable_attribute(:#{validation_method}) || []
+ end
+ end_eval
+ end
end
# All of the following validations are defined in the class scope of the model that you're interested in validating.
@@ -324,43 +343,6 @@ module ActiveRecord
# end
#
# This usage applies to #validate_on_create and #validate_on_update as well.
- def validate(*methods, &block)
- methods << block if block_given?
- write_inheritable_set(:validate, methods)
- end
-
- def validate_on_create(*methods, &block)
- methods << block if block_given?
- write_inheritable_set(:validate_on_create, methods)
- end
-
- def validate_on_update(*methods, &block)
- methods << block if block_given?
- write_inheritable_set(:validate_on_update, methods)
- end
-
- def condition_block?(condition)
- condition.respond_to?("call") && (condition.arity == 1 || condition.arity == -1)
- end
-
- # Determine from the given condition (whether a block, procedure, method or string)
- # whether or not to validate the record. See #validates_each.
- def evaluate_condition(condition, record)
- case condition
- when Symbol; record.send(condition)
- when String; eval(condition, record.instance_eval { binding })
- else
- if condition_block?(condition)
- condition.call(record)
- else
- raise(
- ActiveRecordError,
- "Validations need to be either a symbol, string (to be eval'ed), proc/method, or " +
- "class implementing a static validation method"
- )
- end
- end
- end
# Validates each attribute against a block.
#
@@ -379,20 +361,17 @@ module ActiveRecord
# method, proc or string should return or evaluate to a true or false value.
# * <tt>unless</tt> - Specifies a method, proc or string to call to determine if the validation should
# not occur (e.g. :unless => :skip_validation, or :unless => Proc.new { |user| user.signup_step <= 2 }). The
- # method, proc or string should return or evaluate to a true or false value.
+ # method, proc or string should return or evaluate to a true or false value.
def validates_each(*attrs)
options = attrs.extract_options!.symbolize_keys
attrs = attrs.flatten
# Declare the validation.
- send(validation_method(options[:on] || :save)) do |record|
- # Don't validate when there is an :if condition and that condition is false or there is an :unless condition and that condition is true
- unless (options[:if] && !evaluate_condition(options[:if], record)) || (options[:unless] && evaluate_condition(options[:unless], record))
- attrs.each do |attr|
- value = record.send(attr)
- next if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank])
- yield record, attr, value
- end
+ send(validation_method(options[:on] || :save), options) do |record|
+ attrs.each do |attr|
+ value = record.send(attr)
+ next if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank])
+ yield record, attr, value
end
end
end
@@ -515,11 +494,9 @@ module ActiveRecord
# can't use validates_each here, because it cannot cope with nonexistent attributes,
# while errors.add_on_empty can
- send(validation_method(configuration[:on])) do |record|
- unless (configuration[:if] && !evaluate_condition(configuration[:if], record)) || (configuration[:unless] && evaluate_condition(configuration[:unless], record))
- record.errors.add_on_blank(attr_names, configuration[:message])
- end
- end
+ send(validation_method(configuration[:on]), configuration) do |record|
+ record.errors.add_on_blank(attr_names, configuration[:message])
+ end
end
# Validates that the specified attribute matches the length restrictions supplied. Only one option can be used at a time:
@@ -911,13 +888,7 @@ module ActiveRecord
end
end
-
private
- def write_inheritable_set(key, methods)
- existing_methods = read_inheritable_attribute(key) || []
- write_inheritable_attribute(key, existing_methods | methods)
- end
-
def validation_method(on)
case on
when :save then :validate
@@ -959,14 +930,14 @@ module ActiveRecord
def valid?
errors.clear
- run_validations(:validate)
+ run_callbacks(:validate)
validate
if new_record?
- run_validations(:validate_on_create)
+ run_callbacks(:validate_on_create)
validate_on_create
else
- run_validations(:validate_on_update)
+ run_callbacks(:validate_on_update)
validate_on_update
end
@@ -990,36 +961,5 @@ module ActiveRecord
# Overwrite this method for validation checks used only on updates.
def validate_on_update # :doc:
end
-
- private
- def run_validations(validation_method)
- validations = self.class.read_inheritable_attribute(validation_method.to_sym)
- if validations.nil? then return end
- validations.each do |validation|
- if validation.is_a?(Symbol)
- self.send(validation)
- elsif validation.is_a?(String)
- eval(validation, binding)
- elsif validation_block?(validation)
- validation.call(self)
- elsif validation_class?(validation, validation_method)
- validation.send(validation_method, self)
- else
- raise(
- ActiveRecordError,
- "Validations need to be either a symbol, string (to be eval'ed), proc/method, or " +
- "class implementing a static validation method"
- )
- end
- end
- end
-
- def validation_block?(validation)
- validation.respond_to?("call") && (validation.arity == 1 || validation.arity == -1)
- end
-
- def validation_class?(validation, validation_method)
- validation.respond_to?(validation_method)
- end
end
end