Skip to content

Commit 1ab9de5

Browse files
Merge pull request rails#44625 from jonathanhefner/serialize_cast_value
Avoid double type cast when serializing attributes
2 parents 9aecf3c + 8e383fd commit 1ab9de5

30 files changed

+258
-40
lines changed

activemodel/lib/active_model/attribute.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ def type_cast(value)
179179
type.cast(value)
180180
end
181181

182+
def value_for_database
183+
Type::SerializeCastValue.serialize(type, value)
184+
end
185+
182186
def came_from_user?
183187
!type.value_constructed_by_mass_assignment?(value_before_type_cast)
184188
end

activemodel/lib/active_model/type.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22

33
require "active_model/type/helpers"
4+
require "active_model/type/serialize_cast_value"
45
require "active_model/type/value"
56

67
require "active_model/type/big_integer"

activemodel/lib/active_model/type/big_integer.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ module Type
2121
# All casting and serialization are performed in the same way as the
2222
# standard ActiveModel::Type::Integer type.
2323
class BigInteger < Integer
24+
include SerializeCastValue
25+
26+
def serialize_cast_value(value) # :nodoc:
27+
value
28+
end
29+
2430
private
2531
def max_value
2632
::Float::INFINITY

activemodel/lib/active_model/type/boolean.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ module Type
1010
# - Empty strings are coerced to +nil+.
1111
# - All other values will be coerced to +true+.
1212
class Boolean < Value
13+
include SerializeCastValue
14+
1315
FALSE_VALUES = [
1416
false, 0,
1517
"0", :"0",

activemodel/lib/active_model/type/date.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ module Type
2222
# String values are parsed using the ISO 8601 date format. Any other values
2323
# are cast using their +to_date+ method, if it exists.
2424
class Date < Value
25+
include SerializeCastValue
2526
include Helpers::Timezone
2627
include Helpers::AcceptsMultiparameterTime.new
2728

activemodel/lib/active_model/type/date_time.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ module Type
3838
# attribute :start, :datetime, precision: 4
3939
# end
4040
class DateTime < Value
41+
include SerializeCastValue
4142
include Helpers::Timezone
4243
include Helpers::TimeValue
4344
include Helpers::AcceptsMultiparameterTime.new(
@@ -48,6 +49,8 @@ def type
4849
:datetime
4950
end
5051

52+
alias :serialize_cast_value :serialize_time_value # :nodoc:
53+
5154
private
5255
def cast_value(value)
5356
return apply_seconds_precision(value) unless value.is_a?(::String)

activemodel/lib/active_model/type/decimal.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ module Type
3232
# attribute :weight, :decimal, precision: 24
3333
# end
3434
class Decimal < Value
35+
include SerializeCastValue
3536
include Helpers::Numeric
3637
BIGDECIMAL_PRECISION = 18
3738

activemodel/lib/active_model/type/float.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ module Type
2626
# - <tt>"-Infinity"</tt> is cast to <tt>-Float::INFINITY</tt>.
2727
# - <tt>"NaN"</tt> is cast to <tt>Float::NAN</tt>.
2828
class Float < Value
29+
include SerializeCastValue
2930
include Helpers::Numeric
3031

3132
def type

activemodel/lib/active_model/type/helpers/time_value.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def serialize(value)
2020

2121
value
2222
end
23+
alias :serialize_time_value :serialize
2324

2425
def apply_seconds_precision(value)
2526
return value unless precision && value.respond_to?(:nsec)

activemodel/lib/active_model/type/immutable_string.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ module Type
3333
#
3434
# person.active # => "aye"
3535
class ImmutableString < Value
36+
include SerializeCastValue
37+
3638
def initialize(**args)
3739
@true = -(args.delete(:true)&.to_s || "t")
3840
@false = -(args.delete(:false)&.to_s || "f")

0 commit comments

Comments
 (0)