aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/persistence.rb
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2014-11-05 10:59:50 -0700
committerSean Griffin <sean@thoughtbot.com>2014-11-05 11:05:16 -0700
commit8fee923888192a658d8823b31e77ed0683dfd665 (patch)
tree27b28c9971a98e770e1a14c4be46174754f0f6d7 /activerecord/lib/active_record/persistence.rb
parent00ae750b23f0f9f59fd7058fc3bff043d2a04c5f (diff)
downloadrails-8fee923888192a658d8823b31e77ed0683dfd665.tar.gz
rails-8fee923888192a658d8823b31e77ed0683dfd665.tar.bz2
rails-8fee923888192a658d8823b31e77ed0683dfd665.zip
Improve performance of AR object instantiation
We introduced a performance hit by adding an additional iteration through a model's attributes on creation. We don't actually need the values from `Result` to be a hash, we can separate the columns and values and zip them up ourself during the iteration that we have to do.
Diffstat (limited to 'activerecord/lib/active_record/persistence.rb')
-rw-r--r--activerecord/lib/active_record/persistence.rb28
1 files changed, 25 insertions, 3 deletions
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index 755ff2b2f1..9d2c9d3b9c 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -65,19 +65,41 @@ module ActiveRecord
# how this "single-table" inheritance mapping is implemented.
def instantiate(attributes, column_types = {})
klass = discriminate_class_for_record(attributes)
- attributes = klass.attributes_builder.build_from_database(attributes, column_types)
- klass.allocate.init_with('attributes' => attributes, 'new_record' => false)
+ klass.instantiate_pairs(attributes.keys, attributes.values, column_types)
+ end
+
+ def instantiate_pairs(columns, values, column_types = {}) # :nodoc:
+ attributes = attributes_builder.build_from_database_pairs(columns, values, column_types)
+ allocate.init_with('attributes' => attributes, 'new_record' => false)
+ end
+
+ def instantiate_result_set(result_set, column_types = {}) # :nodoc:
+ inheritance_column_index = inheritance_column && result_set.columns.find_index(inheritance_column)
+
+ result_set.each_pair.map do |columns, values|
+ inheritance_value = inheritance_column_index && values[inheritance_column_index]
+ klass = discriminate_class_for_value(inheritance_value)
+ klass.instantiate_pairs(columns, values, column_types)
+ end
end
private
# Called by +instantiate+ to decide which class to use for a new
# record instance.
#
- # See +ActiveRecord::Inheritance#discriminate_class_for_record+ for
+ # See +ActiveRecord::Inheritance#discriminate_class_for_value+ for
# the single-table inheritance discriminator.
+ def discriminate_class_for_value(*)
+ self
+ end
+
def discriminate_class_for_record(record)
self
end
+
+ def inheritance_column
+ nil
+ end
end
# Returns true if this object hasn't been saved yet -- that is, a record