1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Simplify attribute type decoration

Using `decorate_matching_attribute_type` is overkill to do that.
This commit is contained in:
Ryuta Kamizono 2020-07-20 02:01:52 +09:00
parent dcf545d20c
commit c885086bd0
3 changed files with 24 additions and 27 deletions

View file

@ -64,21 +64,14 @@ module ActiveRecord
end
module ClassMethods # :nodoc:
private
def inherited(subclass)
super
# 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
def define_attribute(name, cast_type, **)
if create_time_zone_conversion_attribute?(name, cast_type)
cast_type = TimeZoneConverter.new(cast_type)
end
super
end
private
def create_time_zone_conversion_attribute?(name, cast_type)
enabled_for_column = time_zone_aware_attributes &&
!skip_time_zone_conversion_for_attributes.include?(name.to_sym)

View file

@ -165,20 +165,12 @@ module ActiveRecord
super
end
private
# 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 `lock_optimistically`, or
# `locking_column` would not be picked up.
def inherited(subclass)
subclass.class_eval do
is_lock_column = ->(name, _) { lock_optimistically && name == locking_column }
decorate_matching_attribute_types(is_lock_column, "_optimistic_locking") do |type|
LockingType.new(type)
end
end
super
def define_attribute(name, cast_type, **) # :nodoc:
if lock_optimistically && name == locking_column
cast_type = LockingType.new(cast_type)
end
super
end
end
end

View file

@ -70,13 +70,25 @@ module ActiveRecord
test "extra options are forwarded to the type caster constructor" do
klass = Class.new(OverloadedType) do
attribute :starts_at, :datetime, precision: 3, limit: 2, scale: 1
attribute :starts_at, :datetime, precision: 3, limit: 2, scale: 1, default: -> { Time.now.utc }
end
starts_at_type = klass.type_for_attribute(:starts_at)
assert_equal 3, starts_at_type.precision
assert_equal 2, starts_at_type.limit
assert_equal 1, starts_at_type.scale
assert_instance_of Time, klass.new.starts_at
end
test "time zone aware attribute" do
with_timezone_config aware_attributes: true, zone: "Pacific Time (US & Canada)" do
klass = Class.new(OverloadedType) do
attribute :starts_at, :datetime, precision: 3, default: -> { Time.now.utc }
end
assert_instance_of ActiveSupport::TimeWithZone, klass.new.starts_at
end
end
test "nonexistent attribute" do