Ruby on rails Rails十进制在API中作为字符串返回

Ruby on rails Rails十进制在API中作为字符串返回,ruby-on-rails,Ruby On Rails,在我的数据库中有一个名为price的字段,它是一个十进制字段,在JSON API响应中,它作为字符串返回 { "day": "November, 8th", "total_distance": "9km", "avg_ride": "9km", "avg_price": "100.0PLN", "total_price": "100.0" } 我想对允许句点后最多2位的字段应用一些验证,并发现如果使用十进制字段,则可以在DB级别应用精度 t、 十进制价格

在我的数据库中有一个名为price的字段,它是一个十进制字段,在JSON API响应中,它作为字符串返回

{
    "day": "November, 8th",
    "total_distance": "9km",
    "avg_ride": "9km",
    "avg_price": "100.0PLN",
    "total_price": "100.0"
}
我想对允许句点后最多2位的字段应用一些验证,并发现如果使用十进制字段,则可以在DB级别应用精度

t、 十进制价格,精度:10,刻度:2

然后我想计算服务对象中的总价:

服务/统计/每月乘车次数\u generator.rb app/api/statistics/stats_api.rb 但在API响应中,该字段是一个字符串

{
    "day": "November, 8th",
    "total_distance": "9km",
    "avg_ride": "9km",
    "avg_price": "100.0PLN",
    "total_price": "100.0"
}
我希望此字段在保存时返回,因为我需要在前端输入一个浮点/十进制数,然后再进行其他计算


当它是十进制字段时,为什么返回字符串?如何修复它?

解决此问题的一种方法是在序列化程序中将其强制转换为所需的类型:

# app/serializers/your_model_serializer.rb

class YourModelSerializer < ActiveModel::Serializer
  attributes :day,
             :total_distance,
             :avg_ride,
             :avg_price,
             :total_price

  def total_price
    object.total_price.to_f
  end
end

解决此问题的一种方法是在序列化程序中将其强制转换为所需的类型:

# app/serializers/your_model_serializer.rb

class YourModelSerializer < ActiveModel::Serializer
  attributes :day,
             :total_distance,
             :avg_ride,
             :avg_price,
             :total_price

  def total_price
    object.total_price.to_f
  end
end

它以字符串形式返回,因为在ruby中Decimal/BigDecimal是一个非常精确的数字。Javascript/JSON没有ruby的BigDecimal那样精确的数据类型

如果打开控制台,您可以在浏览器中轻松看到:

如果将该值转换为序列化程序中的浮点值,那么它将是API返回的JSON对象中的浮点值,但是您需要注意客户机如何使用这些数据。如果他们不使用一个能够处理精度的库,那么你将得到舍入误差,并且经常会在你的计算中损失一分钱


我一直在使用decimal.js库处理类似的事情,结果非常好

它以字符串形式返回,因为在ruby中Decimal/BigDecimal是一个非常精确的数字。Javascript/JSON没有ruby的BigDecimal那样精确的数据类型

如果打开控制台,您可以在浏览器中轻松看到:

如果将该值转换为序列化程序中的浮点值,那么它将是API返回的JSON对象中的浮点值,但是您需要注意客户机如何使用这些数据。如果他们不使用一个能够处理精度的库,那么你将得到舍入误差,并且经常会在你的计算中损失一分钱


我一直在使用decimal.js库处理类似的事情,结果非常好

我决定通过将列类型更改为Float、将其重命名为price_cents、添加money rails并将列货币化来解决这个问题。然后,我只需在显示值或在API响应中将其发送到前端之前调用或舍入值。

我决定通过将列类型更改为Float、将其重命名为price\u cents、添加money rails和将列货币化来解决此问题。然后我只需在显示值或在API响应中将其发送到前端之前调用f或对值进行四舍五入。

我应该使用Money gem将其转换为Float吗?我应该使用Money gem将其转换为Float吗?如果此方法未在模型上定义怎么办?我在服务对象中定义了这个方法。这仍然有效吗?当然,您可以从序列化程序调用服务对象,而不是object.total\u price.to\u f。编辑:这是假设您正在调用与序列化程序关联的控制器上的操作,例如YourModelController和YourModelSerializer。如果您使用有关total_price方法定义位置的更多详细信息更新问题,则控制器的外观,等等。我可以提供一个更明确的答案。我能不能不简单地调用它?好吧,我不确定当你像现在这样在路由中直接调用服务对象时Rails的行为如何…当你使用更传统的控制器+序列化器约定时,我的解决方案会起作用,其中ActiveModel::Serializer的子类为您提供了对Rails如何序列化响应的更多控制?我在服务对象中定义了这个方法。这仍然有效吗?当然,您可以从序列化程序调用服务对象,而不是object.total\u price.to\u f。编辑:这是假设您正在调用与序列化程序关联的控制器上的操作,例如YourModelController和YourModelSerializer。如果您使用有关total_price方法定义位置的更多详细信息更新问题,则控制器的外观,等等。我可以提供一个更明确的答案。我能不能不简单地调用它?好吧,我不确定当你像现在这样在路由中直接调用服务对象时Rails的行为如何…当你使用更传统的控制器+序列化器约定时,我的解决方案会起作用,其中ActiveModel::Serializer的子类使您能够更好地控制Rails如何序列化响应。我在db中进行了一些精度验证,在周期结束后将数字四舍五入到2位,我的客户在周期结束后只会得到最多2位的数字,所以这不是一个问题,我认为我们不应该对客户如何使用数据小心。API应该是自治的
独立于其客户。相反,客户机应该知道API JSON模式。这取决于API设计人员选择将其呈现为字符串还是十进制.Thanx作为基本原理。我在db中进行了一些精度验证,在周期结束后将数字四舍五入到2位,我的客户在周期结束后只会得到最多2位的数字,所以这不是一个问题,我认为我们不应该对客户如何使用数据小心。API应该是自主的,独立于客户端。相反,客户机应该知道API JSON模式。这取决于API设计者在将其呈现为字符串还是十进制之间进行选择。