From 24485b9ef0b9d02d3dcacf16d9e4127f235228cb Mon Sep 17 00:00:00 2001 From: Marcin Raczkowski Date: Sun, 3 Oct 2010 14:08:18 +0200 Subject: Separated initialization --- activerecord/lib/active_record/base.rb | 33 +++++++------------------- activerecord/lib/active_record/identity_map.rb | 11 +++++++++ 2 files changed, 20 insertions(+), 24 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index c12633347e..47cfeb89ba 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -878,42 +878,25 @@ module ActiveRecord #:nodoc: finder_needs_type_condition? ? @relation.where(type_condition) : @relation end - def instantiate_without_im(object, record) - object.instance_variable_set(:@attributes, record) - object.instance_variable_set(:@attributes_cache, {}) - object.instance_variable_set(:@new_record, false) - object.instance_variable_set(:@readonly, false) - object.instance_variable_set(:@destroyed, false) - object.instance_variable_set(:@marked_for_destruction, false) - object.instance_variable_set(:@previously_changed, {}) - object.instance_variable_set(:@changed_attributes, {}) - - object - end - # Finder methods must instantiate through this method to work with the # single-table inheritance model that makes it possible to create # objects of different types from the same table. def instantiate(record) sti_class = find_sti_class(record[inheritance_column]) record_id = sti_class.primary_key && record[sti_class.primary_key] + if ActiveRecord::IdentityMap.enabled? && record_id - if object = identity_map.get(sti_class.name, record_id) - object.instance_variable_get("@attributes_cache").replace({}) - object.instance_variable_get("@changed_attributes").update(record.slice(*object.changed)) - object.instance_variable_get("@attributes").update(record.except(*object.changed)) + if instance = identity_map.get(sti_class.name, record_id) + instance.reinit_with('attributes' => record) else - object = instantiate_without_im(sti_class.allocate, record) - identity_map.add(object) + instance = sti_class.allocate.init_with('attributes' => record) + identity_map.add(instance) end else - object = instantiate_without_im(sti_class.allocate, record) + instance = sti_class.allocate.init_with('attributes' => record) end - object.send(:_run_find_callbacks) - object.send(:_run_initialize_callbacks) - - object + instance end def find_sti_class(type_name) @@ -1452,6 +1435,8 @@ MSG @persisted = true _run_find_callbacks _run_initialize_callbacks + + self end # Returns a String, which Action Pack uses for constructing an URL to this diff --git a/activerecord/lib/active_record/identity_map.rb b/activerecord/lib/active_record/identity_map.rb index 511573d497..c9edd441a4 100644 --- a/activerecord/lib/active_record/identity_map.rb +++ b/activerecord/lib/active_record/identity_map.rb @@ -52,7 +52,18 @@ module ActiveRecord self.enabled = false module InstanceMethods + # Reinitialize an Identity Map model object from +coder+. + # +coder+ must contain the attributes necessary for initializing an empty + # model object. + def reinit_with(coder) + @previously_changed = changes + @attributes_cache, @changed_attributes = {}, {} + @attributes.update(coder['attributes']) + _run_find_callbacks + + self + end end module ClassMethods -- cgit v1.2.3