Skip to content

Commit 8d9f525

Browse files
Clarify numeric casting behavior for blank strings [ci-skip]
`ActiveModel::Type::Decimal`, `ActiveModel::Type::Float`, and `ActiveModel::Type::Integer` cast blank strings to `nil` rather than casting them with `to_d`, `to_f`, or `to_i`. This commit clarifies that behavior in each type's documentation.
1 parent d69501a commit 8d9f525

File tree

3 files changed

+35
-16
lines changed

3 files changed

+35
-16
lines changed

activemodel/lib/active_model/type/decimal.rb

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,24 @@ module Type
1313
# attribute :weight, :decimal
1414
# end
1515
#
16+
# Numeric instances are converted to BigDecimal instances. Any other objects
17+
# are cast using their +to_d+ method, except for blank strings, which are
18+
# cast to +nil+. If a +to_d+ method is not defined, the object is converted
19+
# to a string using +to_s+, which is then cast using +to_d+.
20+
#
1621
# bag = BagOfCoffee.new
17-
# bag.weight = "0.0001"
1822
#
19-
# bag.weight # => 0.1e-3
23+
# bag.weight = 0.01
24+
# bag.weight # => 0.1e-1
2025
#
21-
# Numeric instances are converted to BigDecimal instances. Any other objects
22-
# are cast using their +to_d+ method, if it exists. If it does not exist,
23-
# the object is converted to a string using +to_s+, which is then coerced to
24-
# a BigDecimal using +to_d+.
26+
# bag.weight = "0.01"
27+
# bag.weight # => 0.1e-1
28+
#
29+
# bag.weight = ""
30+
# bag.weight # => nil
31+
#
32+
# bag.weight = :arbitrary
33+
# bag.weight # => nil (the result of `.to_s.to_d`)
2534
#
2635
# Decimal precision defaults to 18, and can be customized when declaring an
2736
# attribute:

activemodel/lib/active_model/type/float.rb

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,24 @@ module Type
1313
# attribute :weight, :float
1414
# end
1515
#
16+
# Values are cast using their +to_f+ method, except for the following
17+
# strings:
18+
#
19+
# - Blank strings are cast to +nil+.
20+
# - <tt>"Infinity"</tt> is cast to <tt>Float::INFINITY</tt>.
21+
# - <tt>"-Infinity"</tt> is cast to <tt>-Float::INFINITY</tt>.
22+
# - <tt>"NaN"</tt> is cast to <tt>Float::NAN</tt>.
23+
#
1624
# bag = BagOfCoffee.new
17-
# bag.weight = "0.25"
1825
#
26+
# bag.weight = "0.25"
1927
# bag.weight # => 0.25
2028
#
21-
# Values are coerced to their float representation using their +to_f+
22-
# methods. However, the following strings which represent floating point
23-
# constants are cast accordingly:
29+
# bag.weight = ""
30+
# bag.weight # => nil
2431
#
25-
# - <tt>"Infinity"</tt> is cast to <tt>Float::INFINITY</tt>.
26-
# - <tt>"-Infinity"</tt> is cast to <tt>-Float::INFINITY</tt>.
27-
# - <tt>"NaN"</tt> is cast to <tt>Float::NAN</tt>.
32+
# bag.weight = "NaN"
33+
# bag.weight # => Float::NAN
2834
class Float < Value
2935
include Helpers::Numeric
3036

activemodel/lib/active_model/type/integer.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,17 @@ module Type
1111
# attribute :age, :integer
1212
# end
1313
#
14+
# Values are cast using their +to_i+ method, except for blank strings, which
15+
# are cast to +nil+. If a +to_i+ method is not defined or raises an error,
16+
# the value will be cast to +nil+.
17+
#
1418
# person = Person.new
15-
# person.age = "18"
1619
#
20+
# person.age = "18"
1721
# person.age # => 18
1822
#
19-
# Values are cast using their +to_i+ method, if it exists. If it does not
20-
# exist, or if it raises an error, the value will be cast to +nil+:
23+
# person.age = ""
24+
# person.age # => nil
2125
#
2226
# person.age = :not_an_integer
2327
# person.age # => nil (because Symbol does not define #to_i)

0 commit comments

Comments
 (0)