From 74af9f7fd781501e7f4a4746afd91b1bd5f77ddc Mon Sep 17 00:00:00 2001 From: Sean Griffin Date: Mon, 16 Jun 2014 14:55:01 -0600 Subject: Promote time zone aware attributes to a first class type decorator This refactoring revealed the need for another form of decoration, which takes a proc to select which it applies to (There's a *lot* of cases where this form can be used). To avoid duplication, we can re-implement the old decoration in terms of the proc-based decoration. The reason we're `instance_exec`ing the matcher is for cases such as time zone aware attributes, where a decorator is defined in a parent class, and a method called in the matcher is overridden by a child class. The matcher will close over the parent, and evaluate in its context, which is not the behavior we want. --- .../test/cases/attribute_decorators_test.rb | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'activerecord/test/cases/attribute_decorators_test.rb') diff --git a/activerecord/test/cases/attribute_decorators_test.rb b/activerecord/test/cases/attribute_decorators_test.rb index 35393753a2..bc3e9a8cf5 100644 --- a/activerecord/test/cases/attribute_decorators_test.rb +++ b/activerecord/test/cases/attribute_decorators_test.rb @@ -110,5 +110,26 @@ module ActiveRecord assert_equal 'whatever decorated!', column.default end + + class Multiplier < SimpleDelegator + def type_cast_from_user(value) + return if value.nil? + value * 2 + end + alias type_cast_from_database type_cast_from_user + end + + test "decorating with a proc" do + Model.attribute :an_int, Type::Integer.new + type_is_integer = proc { |_, type| type.type == :integer } + Model.decorate_matching_attribute_types type_is_integer, :multiplier do |type| + Multiplier.new(type) + end + + model = Model.new(a_string: 'whatever', an_int: 1) + + assert_equal 'whatever', model.a_string + assert_equal 2, model.an_int + end end end -- cgit v1.2.3