aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
diff options
context:
space:
mode:
authorSean Griffin & Sean Doyle <sean+seandoyle@thoughtbot.com>2014-06-27 10:23:43 -0600
committerSean Griffin <sean@thoughtbot.com>2014-06-27 11:33:32 -0600
commitccc1d3dbbec878309ea99839bb8ea2f8aca4dd72 (patch)
tree4678bf1eac2b61f9224b5300697e5b1252e060a3 /activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
parent11ac0cad081eb418dfabe8a427332347beb12a0e (diff)
downloadrails-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.rb20
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) &&