小数的Rails JSON序列化添加引号

问题描述

| 我正在为具有许多十进制和整数属性的模型使用默认的JSON序列化。一个示例结果是:
{ \"user\": { \"id\": 1234,\"rating\": \"98.7\" } }
请注意,在\“ rating \”值附近添加了引号。这会导致我正在使用的反序列化库将它们错误地视为字符串(而不是小数)。可以将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
    

解决方法

将小数从语言A传递到语言B的唯一“安全”方法是使用字符串。如果您的json包含
\"rating\": 98.79999999999999
,则JavaScript运行时可能会将其转换为
98.79999999999998
。 请参阅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
    ,Rails 4.0的选项已更改为ѭ6,因此您可以指定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的美元金额抽出字符串的问题。     ,如果使用ActiveModel :: Serializer,则还可以使用to_f强制从Decimal转换为Float类型。这也将为您节省报价! 所以在您的对象序列化器类中。做
def rating
  self.rating.to_f
end
    ,使用Rails 5时,encode_big_decimal_as_string不起作用(已弃用,因此在此不会感到惊讶)。 如果将jbuilder添加到您的应用程序
# Gemfile
gem \'jbuilder\',\'~> 2.5\'
然后只需创建一个json视图,将小数转换为仅用于该视图的float即可,您应该是黄金的。
# app/views/yourmodel/index.json.jbuilder
json.array! @yourmodels do |yourmodel|
  json.attributethatisadecimal yourmodel.attributethatisadecimal.to_f
end
这对我来说效果很好-要做更​​多的工作(因为您必须将模型映射到jbuilder),但是这种方法看起来很干净。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...