我正在为具有多个十进制和整数属性的模型使用默认的JSON序列化.一个示例结果是:
{ "user": { "id": 1234, "rating": "98.7" } }
请注意在"评级"值附近添加引号.这导致我正在使用的反序列化库错误地将它们视为字符串(而不是小数).可以将Rails设置为不使用所有小数的引号吗?
编辑:
如果这有所不同,我在Rails 3.0.7和Ruby 1.9.2上.
编辑:
终奌站:
rails g model user rating:decimal
rake db:migrate
安慰:
user = User.create(rating: 98.7)
user.to_json
Mar*_*rth 44
将小数字从A语言移到语言B的唯一"安全"方法是使用String.如果你的json包含"rating": 98.79999999999999它,它可能会98.79999999999998被你的JavaScript运行时转换.
请参阅BigDecimal as_json文档:
BigDecimal自然会表示为JSON数字.但是,大多数库直接将非整数JSON数解析为浮点数.使用这些库的客户端通常会得到错误的数字,除了使用JSON代码本身手动检查字符串之外,无法恢复.
这就是返回JSON字符串的原因.JSON文字不是数字,但如果另一端通过契约知道数据应该是BigDecimal,它仍然有机会对字符串进行后处理并获得实际值.
如果你想强制Rails不引用这些,你可以修补BigDecimal(参见Rails 源代码).
# not needed: to compare with the Numeric implementation
class Numeric
  def as_json(options = nil) self end #:nodoc:
  def encode_json(encoder) to_s end #:nodoc:
end
class BigDecimal
  def as_json(options = nil) self end
  def encode_json(encoder) to_s end #:nodoc:
end
tox*_*xaq 28
对于具有选项的Rails 4.0,这已经改变,ActiveSupport.encode_big_decimal_as_string以便您可以指定BigDecimal序列化首选项.见问题6033
与此同时,如果您对6033中提出的参数感到满意,并且您运行的Rails版本低于4.0,则可以修改BigDecimal,如下所示
require 'bigdecimal'
class BigDecimal
  def as_json(options = nil) #:nodoc:
    if finite?
      self
    else
      NilClass::AS_JSON
    end
  end
end
这解决了我的问题,RABL抽出存储为BigDecimal的美元金额的字符串.
ale*_*xzg 10
如果您使用的是ActiveModel :: Serializer,您还可以使用to_f强制从Decimal转换为Float类型.那也会为你剪掉报价!
所以在你的对象序列化器类中.做
def rating
  self.rating.to_f
end
| 归档时间: | 
 | 
| 查看次数: | 16668 次 | 
| 最近记录: |