From 4f37b97033f596ec2c95eb53e9964e051c224981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 8 Sep 2009 10:10:14 -0500 Subject: Changed ActiveRecord to use new callbacks and speed up observers by only notifying events that are actually being consumed. Signed-off-by: Joshua Peek --- activemodel/lib/active_model/validations.rb | 16 +++++---- .../lib/active_model/validations/presence.rb | 2 +- activemodel/lib/active_model/validations/with.rb | 2 +- .../lib/active_model/validations_repair_helper.rb | 42 +++++++++------------- 4 files changed, 28 insertions(+), 34 deletions(-) (limited to 'activemodel/lib') diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb index 7d49e60790..72898726d1 100644 --- a/activemodel/lib/active_model/validations.rb +++ b/activemodel/lib/active_model/validations.rb @@ -6,7 +6,7 @@ require 'active_support/callbacks' module ActiveModel module Validations extend ActiveSupport::Concern - include ActiveSupport::Callbacks + include ActiveSupport::NewCallbacks included do define_callbacks :validate @@ -64,7 +64,7 @@ module ActiveModel attrs = attrs.flatten # Declare the validation. - send(validation_method(options[:on]), options) do |record| + validate options do |record| attrs.each do |attr| value = record.send(:read_attribute_for_validation, attr) next if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank]) @@ -73,10 +73,14 @@ module ActiveModel end end - private - def validation_method(on) - :validate + def validate(*args, &block) + options = args.last + if options.is_a?(Hash) && options.key?(:on) + options[:if] = Array(options[:if]) + options[:if] << "@_on_validate == :#{options[:on]}" end + set_callback(:validate, :before, *args, &block) + end end # Returns the Errors object that holds all information about attribute error messages. @@ -87,7 +91,7 @@ module ActiveModel # Runs all the specified validations and returns true if no errors were added otherwise false. def valid? errors.clear - run_callbacks(:validate) + _run_validate_callbacks errors.empty? end diff --git a/activemodel/lib/active_model/validations/presence.rb b/activemodel/lib/active_model/validations/presence.rb index 72d6b1c6f0..3ff677c137 100644 --- a/activemodel/lib/active_model/validations/presence.rb +++ b/activemodel/lib/active_model/validations/presence.rb @@ -32,7 +32,7 @@ module ActiveModel # can't use validates_each here, because it cannot cope with nonexistent attributes, # while errors.add_on_empty can - send(validation_method(configuration[:on]), configuration) do |record| + validate configuration do |record| record.errors.add_on_blank(attr_names, configuration[:message]) end end diff --git a/activemodel/lib/active_model/validations/with.rb b/activemodel/lib/active_model/validations/with.rb index 851cdfebf0..edc2133ddc 100644 --- a/activemodel/lib/active_model/validations/with.rb +++ b/activemodel/lib/active_model/validations/with.rb @@ -51,7 +51,7 @@ module ActiveModel def validates_with(*args) configuration = args.extract_options! - send(validation_method(configuration[:on]), configuration) do |record| + validate configuration do |record| args.each do |klass| klass.new(record, configuration.except(:on, :if, :unless)).validate end diff --git a/activemodel/lib/active_model/validations_repair_helper.rb b/activemodel/lib/active_model/validations_repair_helper.rb index 0809e7c0d1..40741e6dbe 100644 --- a/activemodel/lib/active_model/validations_repair_helper.rb +++ b/activemodel/lib/active_model/validations_repair_helper.rb @@ -2,44 +2,34 @@ module ActiveModel module ValidationsRepairHelper extend ActiveSupport::Concern - module Toolbox - def self.record_validations(*model_classes) - model_classes.inject({}) do |repair, klass| - repair[klass] ||= {} - [:validate, :validate_on_create, :validate_on_update].each do |callback| - ivar = "@#{callback.to_s}_callbacks" - the_callback = klass.instance_variable_get(ivar) if klass.instance_variable_defined?(ivar) - repair[klass][callback] = (the_callback.nil? ? nil : the_callback.dup) - end - repair - end - end - - def self.reset_validations(recorded) - recorded.each do |klass, repairs| - [:validate, :validate_on_create, :validate_on_update].each do |callback| - klass.instance_variable_set("@#{callback.to_s}_callbacks", repairs[callback]) - end - end - end - end - module ClassMethods def repair_validations(*model_classes) setup do - @validation_repairs = Toolbox.record_validations(*model_classes) + @_stored_callbacks = {} + model_classes.each do |k| + @_stored_callbacks[k] = k._validate_callbacks.dup + end end teardown do - Toolbox.reset_validations(@validation_repairs) + model_classes.each do |k| + k._validate_callbacks = @_stored_callbacks[k] + k.__update_callbacks(:validate) + end end end end def repair_validations(*model_classes, &block) - validation_repairs = Toolbox.record_validations(*model_classes) + @__stored_callbacks = {} + model_classes.each do |k| + @__stored_callbacks[k] = k._validate_callbacks.dup + end return block.call ensure - Toolbox.reset_validations(validation_repairs) + model_classes.each do |k| + k._validate_callbacks = @__stored_callbacks[k] + k.__update_callbacks(:validate) + end end end end -- cgit v1.2.3 From 2ea1d684d93bd59887a9fd12e647941f0d1f4868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 8 Sep 2009 10:22:45 -0500 Subject: Refactor new callbacks and AR implementation. Signed-off-by: Joshua Peek --- activemodel/lib/active_model/validations.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'activemodel/lib') diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb index 72898726d1..edeb508a08 100644 --- a/activemodel/lib/active_model/validations.rb +++ b/activemodel/lib/active_model/validations.rb @@ -9,7 +9,7 @@ module ActiveModel include ActiveSupport::NewCallbacks included do - define_callbacks :validate + define_callbacks :validate, :scope => :name end module ClassMethods @@ -79,7 +79,7 @@ module ActiveModel options[:if] = Array(options[:if]) options[:if] << "@_on_validate == :#{options[:on]}" end - set_callback(:validate, :before, *args, &block) + set_callback(:validate, *args, &block) end end -- cgit v1.2.3