【问题标题】:How to deal with Money in Rails and Mongoid如何在 Rails 和 Mongoid 中处理金钱
【发布时间】:2016-01-22 10:13:06
【问题描述】:

我知道以前有人问过这个问题,但我发现的大多数答案都与 ActiveRecord 或旧的(大多数情况下,两者都有)有关,我想知道是否对此有新的看法。

简而言之,我的 Rails 应用程序是一个 API,所以请记住这一点(通常不能使用很多有用的小视图相关帮助器)。

我一直在阅读这方面的内容,发现MoneyRails 看起来很整洁。我遇到的问题是,当我检索数据时,它返回一个对象而不是可用值:

class MyModel
  include Mongoid::Document
  ...
  field :price_GBP,  type: Money
  ...
end

所以为了创建文档,我发送了一个号码,它创建的文档很好。现在,当我查询同一个文档时,它会返回 price_GBP 的对象,这很好,但我的主要观点是它返回值 fractional,就像在 my_obj.price_GBP[:fractional] 中一样,作为字符串而不是数字。

我宁愿让我的客户不必将字符串转换为数字而不是十进制。

我想我可以创建一个小助手,在这样的情况下转换值(在我的模型中):

def my_helper
  self.price_GBP = BigDecimal(self.price_GBP) # or something along those lines
end

然后在我的控制器中:

@my_model = Model.find(id)
@my_model.price_GBP = @my_model.price_GBP = @my_model.my_helper
render json: @my_model

考虑到上述情况,这是最好的方法吗?如果是,那么使用 MoneyRails gem 有什么意义呢?

其次,如果不使用 MoneyRails gem,我应该使用BigDecimal 还是Float 作为字段类型?

当我尝试BigDecimal 时,数据保存正常,但是当我检索它时,我得到的是一个字符串而不是一个数字。这是正确的行为吗?

当我尝试Float 时,一切正常,但我在某处读到Float 不是最准确的。

你有什么想法?

【问题讨论】:

  • 您能否添加一个 irb/pry 会话来显示您在本段中描述的内容:“因此,要创建文档,我发送了一个数字,它创建的文档很好。现在,当我查询相同的文档时,它返回price_GBP 的对象,这很好,但我的主要观点是它返回 my_obj.price_GBP[:fractional] 中的小数值作为字符串而不是数字。” ?如果可能,请说明实际结果是什么以及您的预期是什么?

标签: ruby-on-rails ruby ruby-on-rails-4 mongoid


【解决方案1】:

如果您计划对货币值执行任何类型的算术运算,请避免使用FloatBigDecimal 很好,或者您也可以用美分表示值并将其存储为Integer。这就是 Money gem 的工作原理。

我的建议是继续使用 MoneyRails gem 并使用 built-in helpers 来输出值。您提到无法使用助手,但我看不出是什么阻止了这一点-Rails 包含jbuilder,它允许您在可以访问所有“有用的小视图相关助手”的视图中制定您的 JSON 结构-例如

# app/views/someresource/show.json.jbuilder

# ...other attributes
json.price_GBP = humanized_money(@my_model.price_GBP)

【讨论】:

  • 我没有任何视图(仅限 API 应用程序),因此助手不起作用。我尝试在我的模型中包含include ActionView::Base,但没有成功。如果我使用 ActionController::Base.helpers.humanized_money 代替工作,虽然不是很优雅。最后,当我使用 jBuilder 时,所有值(包括数字)都以String 发送,这绝对是我不想要的。这是 jBuilder 的标准行为吗?
  • show.json.jbuilder IS 视图 - 所以是的,您确实可以访问视图助手。据我所知,jbuilder 默认情况下不会将数字转换为字符串,因此您的情况可能会发生其他事情。
  • Here 是我创建的描述上述内容的示例应用程序 - 请看一下。如果您希望货币价值以数字形式返回(以便您可以在客户端上执行计算),则使用price.cents 发送回integer 而不是助手。希望这可以帮助。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-30
相关资源
最近更新 更多