价格字段的单位转换
我们在存储一个产品的价格时,字段类型的设计可以有以下几种:
Decimal - 以元为单位存储浮点数
Integer - 以分为单位储存整数
如果用浮点数存储数据,那么我们在表单中录入价格时,时常会遇到一个奇怪的现象,录入的价格是912.00元,而存储数据库时莫名其妙地变成了911.999999999999 。呈现到前端时,就很怪异了。
在ruby中我可以通过下面测试,发现同样问题:
2.3.4 :017 > "9.12".to_f * 100
=> 911.9999999999999因此,我们就有了以分为单位存储的想法。但是,以分为单位,我们在生成表单时,又想让用户以元为单位录入价格,我们可能会这么做:
rails g scaffold product name price_cents:integerclass Product < ApplicationRecord
# 数据库存储价格字段是 price_cents,整形,单位为分
def price
(price_cents || 0) / 100.0
end
def price=(v)
# 这里用.round就是为了解决上面的911.99999999问题
self.price_cents = (v.to_f * 100).round
end
end封装一下代码,做到足够DRY
以上代码,足够应付我们的价格前后端单位转换问题。如果需要更高级的功能,我们可以尝试Gem money 或 money-rails
Last updated