diff options
Diffstat (limited to 'activerecord/lib')
-rw-r--r-- | activerecord/lib/active_record/core.rb | 20 | ||||
-rw-r--r-- | activerecord/lib/active_record/persistence.rb | 8 | ||||
-rw-r--r-- | activerecord/lib/active_record/querying.rb | 7 | ||||
-rw-r--r-- | activerecord/lib/active_record/result.rb | 5 |
4 files changed, 38 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index e1a0b2ecf8..9c9fc77a0d 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -350,6 +350,26 @@ module ActiveRecord end ## + # Initializer used for instantiating objects that have been read from the + # database. +attributes+ should be an attributes object, and unlike the + # `initialize` method, no assignment calls are made per attribute. + # + # :nodoc: + def init_from_db(attributes) + init_internals + + @new_record = false + @attributes = attributes + + yield self if block_given? + + _run_find_callbacks + _run_initialize_callbacks + + self + end + + ## # :method: clone # Identical to Ruby's clone method. This is a "shallow" copy. Be warned that your attributes are not copied. # That means that modifying attributes of the clone will modify the original, since they will both point to the diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb index a0d5f1ee9f..72d92ef504 100644 --- a/activerecord/lib/active_record/persistence.rb +++ b/activerecord/lib/active_record/persistence.rb @@ -67,8 +67,14 @@ module ActiveRecord # how this "single-table" inheritance mapping is implemented. def instantiate(attributes, column_types = {}, &block) klass = discriminate_class_for_record(attributes) + instantiate_instance_of(klass, attributes, column_types, &block) + end + + # Given a class, an attributes hash, +instantiate+ returns a new instance + # of the class. Accepts only keys as strings. + def instantiate_instance_of(klass, attributes, column_types = {}, &block) attributes = klass.attributes_builder.build_from_database(attributes, column_types) - klass.allocate.init_with("attributes" => attributes, "new_record" => false, &block) + klass.allocate.init_from_db(attributes, &block) end # Updates an object (or multiple objects) and saves it to the database, if validations pass. diff --git a/activerecord/lib/active_record/querying.rb b/activerecord/lib/active_record/querying.rb index d33d36ac02..c84f3d0fbb 100644 --- a/activerecord/lib/active_record/querying.rb +++ b/activerecord/lib/active_record/querying.rb @@ -49,7 +49,12 @@ module ActiveRecord } message_bus.instrument("instantiation.active_record", payload) do - result_set.map { |record| instantiate(record, column_types, &block) } + if result_set.includes_column?(inheritance_column) + result_set.map { |record| instantiate(record, column_types, &block) } + else + # Instantiate a homogeneous set + result_set.map { |record| instantiate_instance_of(self, record, column_types, &block) } + end end end diff --git a/activerecord/lib/active_record/result.rb b/activerecord/lib/active_record/result.rb index ffef229be2..3549e8a3fa 100644 --- a/activerecord/lib/active_record/result.rb +++ b/activerecord/lib/active_record/result.rb @@ -43,6 +43,11 @@ module ActiveRecord @column_types = column_types end + # Does this result set include the column named +name+ ? + def includes_column?(name) + @columns.include? name + end + # Returns the number of elements in the rows array. def length @rows.length |