aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/attribute_set
diff options
context:
space:
mode:
authorVijay Dev <vijaydev.cse@gmail.com>2014-11-30 10:28:16 +0000
committerVijay Dev <vijaydev.cse@gmail.com>2014-11-30 10:28:16 +0000
commit079ac4a0584b24625266a0e9448503d1b96c2b7f (patch)
tree6a28edeb393cd095de252335f9e3c9cec7c78d13 /activerecord/lib/active_record/attribute_set
parentbd9ffa7e1fb433f359ee096a2afd924a652d1912 (diff)
parent6874133f9e5ca79f30f43632da4338d7b82ddeff (diff)
downloadrails-079ac4a0584b24625266a0e9448503d1b96c2b7f.tar.gz
rails-079ac4a0584b24625266a0e9448503d1b96c2b7f.tar.bz2
rails-079ac4a0584b24625266a0e9448503d1b96c2b7f.zip
Merge branch 'master' of github.com:rails/rails
Diffstat (limited to 'activerecord/lib/active_record/attribute_set')
-rw-r--r--activerecord/lib/active_record/attribute_set/builder.rb83
1 files changed, 66 insertions, 17 deletions
diff --git a/activerecord/lib/active_record/attribute_set/builder.rb b/activerecord/lib/active_record/attribute_set/builder.rb
index d4a787f2fe..05138ae36d 100644
--- a/activerecord/lib/active_record/attribute_set/builder.rb
+++ b/activerecord/lib/active_record/attribute_set/builder.rb
@@ -1,35 +1,84 @@
module ActiveRecord
class AttributeSet # :nodoc:
class Builder # :nodoc:
- attr_reader :types
+ attr_reader :types, :always_initialized
- def initialize(types)
+ def initialize(types, always_initialized = nil)
@types = types
+ @always_initialized = always_initialized
end
def build_from_database(values = {}, additional_types = {})
- attributes = build_attributes_from_values(values, additional_types)
- add_uninitialized_attributes(attributes)
+ if always_initialized && !values.key?(always_initialized)
+ values[always_initialized] = nil
+ end
+
+ attributes = LazyAttributeHash.new(types, values, additional_types)
AttributeSet.new(attributes)
end
+ end
+ end
- private
+ class LazyAttributeHash # :nodoc:
+ delegate :select, :transform_values, to: :materialize
- def build_attributes_from_values(values, additional_types)
- values.each_with_object({}) do |(name, value), hash|
- type = additional_types.fetch(name, types[name])
- hash[name] = Attribute.from_database(name, value, type)
- end
+ def initialize(types, values, additional_types)
+ @types = types
+ @values = values
+ @additional_types = additional_types
+ @materialized = false
+ @delegate_hash = {}
+ end
+
+ def key?(key)
+ delegate_hash.key?(key) || values.key?(key) || types.key?(key)
+ end
+
+ def [](key)
+ delegate_hash[key] || assign_default_value(key)
+ end
+
+ def []=(key, value)
+ if frozen?
+ raise RuntimeError, "Can't modify frozen hash"
+ end
+ delegate_hash[key] = value
+ end
+
+ def initialized_keys
+ delegate_hash.keys | values.keys
+ end
+
+ def initialize_dup(_)
+ @delegate_hash = delegate_hash.transform_values(&:dup)
+ super
+ end
+
+ protected
+
+ attr_reader :types, :values, :additional_types, :delegate_hash
+
+ private
+
+ def assign_default_value(name)
+ type = additional_types.fetch(name, types[name])
+ value_present = true
+ value = values.fetch(name) { value_present = false }
+
+ if value_present
+ delegate_hash[name] = Attribute.from_database(name, value, type)
+ elsif types.key?(name)
+ delegate_hash[name] = Attribute.uninitialized(name, type)
end
+ end
- def add_uninitialized_attributes(attributes)
- types.each_key do |name|
- next if attributes.key? name
- type = types[name]
- attributes[name] =
- Attribute.uninitialized(name, type)
- end
+ def materialize
+ unless @materialized
+ values.each_key { |key| self[key] }
+ types.each_key { |key| self[key] }
+ @materialized = true
end
+ delegate_hash
end
end
end