diff options
author | Sean Griffin & Sean Doyle <sean+seandoyle@thoughtbot.com> | 2014-06-27 10:23:43 -0600 |
---|---|---|
committer | Sean Griffin <sean@thoughtbot.com> | 2014-06-27 11:33:32 -0600 |
commit | ccc1d3dbbec878309ea99839bb8ea2f8aca4dd72 (patch) | |
tree | 4678bf1eac2b61f9224b5300697e5b1252e060a3 /activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb | |
parent | 11ac0cad081eb418dfabe8a427332347beb12a0e (diff) | |
download | rails-ccc1d3dbbec878309ea99839bb8ea2f8aca4dd72.tar.gz rails-ccc1d3dbbec878309ea99839bb8ea2f8aca4dd72.tar.bz2 rails-ccc1d3dbbec878309ea99839bb8ea2f8aca4dd72.zip |
Stop using instance exec for type decorators
We are moving this behavior out to an object that we would like to keep
separated from `ActiveRecord::Base`, which means not passing the class
object to it. As such, we need to stop using `instance_exec`, and
instead close over the subclass on global type decorators that are
applied in `Base`.
Diffstat (limited to 'activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb')
-rw-r--r-- | activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb index 5f1dc8bc9f..f439bd1ffe 100644 --- a/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb +++ b/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb @@ -33,15 +33,25 @@ module ActiveRecord class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false self.skip_time_zone_conversion_for_attributes = [] - - matcher = ->(name, type) { create_time_zone_conversion_attribute?(name, type) } - decorate_matching_attribute_types(matcher, :_time_zone_conversion) do |type| - TimeZoneConverter.new(type) - end end module ClassMethods private + + def inherited(subclass) + # We need to apply this decorator here, rather than on module inclusion. The closure + # created by the matcher would otherwise evaluate for `ActiveRecord::Base`, not the + # sub class being decorated. As such, changes to `time_zone_aware_attributes`, or + # `skip_time_zone_conversion_for_attributes` would not be picked up. + subclass.class_eval do + matcher = ->(name, type) { create_time_zone_conversion_attribute?(name, type) } + decorate_matching_attribute_types(matcher, :_time_zone_conversion) do |type| + TimeZoneConverter.new(type) + end + end + super + end + def create_time_zone_conversion_attribute?(name, cast_type) time_zone_aware_attributes && !self.skip_time_zone_conversion_for_attributes.include?(name.to_sym) && |