diff options
author | Sean Griffin <sean@thoughtbot.com> | 2014-11-14 12:02:05 -0700 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2014-11-14 14:30:40 -0700 |
commit | 895a53e7161e9bdc6285fe03f16b49ec74972416 (patch) | |
tree | 23a23a7e74fabb8c36c185b0d9d1ca178d2a3bed /activerecord/lib | |
parent | 3f63ac4e4dd22a452a37ad7a654cf5e4f4e66349 (diff) | |
download | rails-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.
Diffstat (limited to 'activerecord/lib')
-rw-r--r-- | activerecord/lib/active_record/attribute_set/builder.rb | 30 |
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 |