mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Avoid double time zone converter decoration when user-defined timestamp attribute with implicit type
If type is given as a symbol, it will lookup a fresh type object via `Type.lookup`, but if type is omitted, `type_for_attribute` will lookup the database type which is already decorated by `define_attribute`. To avoid the double decoration, skip extra decoration if its type is already decorated.
This commit is contained in:
parent
d784043d80
commit
e0366022f6
4 changed files with 20 additions and 0 deletions
|
@ -6,6 +6,10 @@ module ActiveRecord
|
|||
module AttributeMethods
|
||||
module TimeZoneConversion
|
||||
class TimeZoneConverter < DelegateClass(Type::Value) # :nodoc:
|
||||
def self.new(subtype)
|
||||
self === subtype ? subtype : super
|
||||
end
|
||||
|
||||
def deserialize(value)
|
||||
convert_time_to_time_zone(super)
|
||||
end
|
||||
|
|
|
@ -178,6 +178,10 @@ module ActiveRecord
|
|||
# `nil` values to `lock_version`, and not result in `ActiveRecord::StaleObjectError`
|
||||
# during update record.
|
||||
class LockingType < DelegateClass(Type::Value) # :nodoc:
|
||||
def self.new(subtype)
|
||||
self === subtype ? subtype : super
|
||||
end
|
||||
|
||||
def deserialize(value)
|
||||
super.to_i
|
||||
end
|
||||
|
|
|
@ -74,10 +74,12 @@ module ActiveRecord
|
|||
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_kind_of Type::DateTime, starts_at_type
|
||||
assert_instance_of Time, klass.new.starts_at
|
||||
end
|
||||
|
||||
|
@ -85,9 +87,18 @@ module ActiveRecord
|
|||
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 }
|
||||
attribute :ends_at, default: -> { Time.now.utc }
|
||||
end
|
||||
|
||||
starts_at_type = klass.type_for_attribute(:starts_at)
|
||||
ends_at_type = klass.type_for_attribute(:ends_at)
|
||||
|
||||
assert_instance_of AttributeMethods::TimeZoneConversion::TimeZoneConverter, starts_at_type
|
||||
assert_instance_of AttributeMethods::TimeZoneConversion::TimeZoneConverter, ends_at_type
|
||||
assert_kind_of Type::DateTime, starts_at_type.__getobj__
|
||||
assert_kind_of Type::DateTime, ends_at_type.__getobj__
|
||||
assert_instance_of ActiveSupport::TimeWithZone, klass.new.starts_at
|
||||
assert_instance_of ActiveSupport::TimeWithZone, klass.new.ends_at
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1127,6 +1127,7 @@ ActiveRecord::Schema.define do
|
|||
t.string :overloaded_string_with_limit, limit: 255
|
||||
t.string :string_with_default, default: "the original default"
|
||||
t.string :inferred_string, limit: 255
|
||||
t.datetime :starts_at, :ends_at
|
||||
end
|
||||
|
||||
create_table :users, force: true do |t|
|
||||
|
|
Loading…
Reference in a new issue