diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-06-16 17:57:48 -0300 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2014-06-16 17:57:48 -0300 |
commit | 88714deb677f598fa40f6e7b61a083a5461d07fd (patch) | |
tree | 082c0a515260100cf4fac635c896d32e06cf050a | |
parent | 91532738a151f637206906d5afb64e68ec68cec0 (diff) | |
parent | 63bbaaa478a1c0b72e7f381510e6e13faf069d30 (diff) | |
download | rails-88714deb677f598fa40f6e7b61a083a5461d07fd.tar.gz rails-88714deb677f598fa40f6e7b61a083a5461d07fd.tar.bz2 rails-88714deb677f598fa40f6e7b61a083a5461d07fd.zip |
Merge pull request #15759 from sgrif/sg-extract-type-decorator
Refactor application of type decorators into an object
-rw-r--r-- | activerecord/lib/active_record/attribute_decorators.rb | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/activerecord/lib/active_record/attribute_decorators.rb b/activerecord/lib/active_record/attribute_decorators.rb index 596161f81d..928d8cacae 100644 --- a/activerecord/lib/active_record/attribute_decorators.rb +++ b/activerecord/lib/active_record/attribute_decorators.rb @@ -4,7 +4,7 @@ module ActiveRecord included do class_attribute :attribute_type_decorations, instance_accessor: false # :internal: - self.attribute_type_decorations = Hash.new({}) + self.attribute_type_decorations = TypeDecorator.new end module ClassMethods @@ -13,22 +13,38 @@ module ActiveRecord column_name = column_name.to_s # Create new hashes so we don't modify parent classes - decorations_for_column = attribute_type_decorations[column_name] - new_decorations = decorations_for_column.merge(decorator_name.to_s => block) - self.attribute_type_decorations = attribute_type_decorations.merge(column_name => new_decorations) + self.attribute_type_decorations = attribute_type_decorations.merge(column_name, decorator_name, block) end private def add_user_provided_columns(*) super.map do |column| - decorations = attribute_type_decorations[column.name].values - decorated_type = decorations.inject(column.cast_type) do |type, block| - block.call(type) - end + decorated_type = attribute_type_decorations.apply(column.name, column.cast_type) column.with_type(decorated_type) end end end + + class TypeDecorator + delegate :clear, to: :@decorations + + def initialize(decorations = Hash.new({})) + @decorations = decorations + end + + def merge(attribute_name, decorator_name, block) + decorations_for_attribute = @decorations[attribute_name] + new_decorations = decorations_for_attribute.merge(decorator_name.to_s => block) + TypeDecorator.new(@decorations.merge(attribute_name => new_decorations)) + end + + def apply(attribute_name, type) + decorations = @decorations[attribute_name].values + decorations.inject(type) do |new_type, block| + block.call(new_type) + end + end + end end end |