aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Griffin <sean@thoughtbot.com>2014-11-14 12:02:05 -0700
committerSean Griffin <sean@thoughtbot.com>2014-11-14 14:30:40 -0700
commit895a53e7161e9bdc6285fe03f16b49ec74972416 (patch)
tree23a23a7e74fabb8c36c185b0d9d1ca178d2a3bed
parent3f63ac4e4dd22a452a37ad7a654cf5e4f4e66349 (diff)
downloadrails-895a53e7161e9bdc6285fe03f16b49ec74972416.tar.gz
rails-895a53e7161e9bdc6285fe03f16b49ec74972416.tar.bz2
rails-895a53e7161e9bdc6285fe03f16b49ec74972416.zip
Allow `LazyAttributeHash` to be marshalled
`default_proc` makes a hash unmarshallable, and adds unneccessary overhead. Since we control all access to the hash, let's just handle it in that method. This has the side effect of improving performance on initialization (but not neccessarily on access). We'll need to profile further once the tests are passing.
-rw-r--r--activerecord/lib/active_record/attribute_set/builder.rb30
1 files changed, 17 insertions, 13 deletions
diff --git a/activerecord/lib/active_record/attribute_set/builder.rb b/activerecord/lib/active_record/attribute_set/builder.rb
index 54e9cbb779..4134032659 100644
--- a/activerecord/lib/active_record/attribute_set/builder.rb
+++ b/activerecord/lib/active_record/attribute_set/builder.rb
@@ -23,7 +23,7 @@ module ActiveRecord
class LazyAttributeHash
delegate :select, :transform_values, to: :materialize
- delegate :[], :[]=, :freeze, to: :delegate_hash
+ delegate :[]=, :freeze, to: :delegate_hash
def initialize(types, values, additional_types)
@types = types
@@ -31,20 +31,26 @@ module ActiveRecord
@additional_types = additional_types
@materialized = false
@delegate_hash = {}
- assign_default_proc
end
def key?(key)
delegate_hash.key?(key) || values.key?(key) || types.key?(key)
end
+ def [](key)
+ if delegate_hash.key?(key)
+ delegate_hash[key]
+ else
+ assign_default_value(key)
+ end
+ end
+
def initialized_keys
delegate_hash.keys | values.keys
end
def initialize_dup(_)
@delegate_hash = delegate_hash.transform_values(&:dup)
- assign_default_proc
super
end
@@ -59,22 +65,20 @@ module ActiveRecord
private
- def assign_default_proc
- delegate_hash.default_proc = proc do |hash, name|
- type = additional_types.fetch(name, types[name])
+ def assign_default_value(name)
+ type = additional_types.fetch(name, types[name])
- if values.key?(name)
- hash[name] = Attribute.from_database(name, values[name], type)
- elsif types.key?(name)
- hash[name] = Attribute.uninitialized(name, type)
- end
+ if values.key?(name)
+ delegate_hash[name] = Attribute.from_database(name, values[name], type)
+ elsif types.key?(name)
+ delegate_hash[name] = Attribute.uninitialized(name, type)
end
end
def materialize
unless @materialized
- values.each_key { |key| delegate_hash[key] }
- types.each_key { |key| delegate_hash[key] }
+ values.each_key { |key| self[key] }
+ types.each_key { |key| self[key] }
@materialized = true
end
delegate_hash