true do |t| t.decimal "cost", :precision => 10, :scale -6ren">
gpt4 book ai didi

ruby-on-rails - 如何比较 BigDecimal 与 ActiveRecord 小数字段?

转载 作者:行者123 更新时间:2023-12-04 06:14:19 27 4
gpt4 key购买 nike

假设这样一个模式:

create_table "bills", :force => true do |t|
t.decimal "cost", :precision => 10, :scale => 5
end

我想编写一个函数,将新账单写入数据库,前提是它是唯一的。以下不起作用:

def load_bill_unless_exists(candidate)
incumbents = Bill.scoped.where(:cost => candidate.cost)
candidate.save unless incumbents.exists?
end

因为现任法案和候选人法案在他们的 BigDecimal 表示中有不同的限制,所以 :cost => candidate.cost 测试失败。也就是说,它正在比较:

candidate: #<Bill id: nil, cost: #<BigDecimal:105e39850,'0.1670576666 6666666E4',27(27)>>

incumbent: #<ServiceBill id: 198449, cost: #<BigDecimal:105e35840,'0.167057667E4',18(18)>>

请注意,候选人的 BigDecimal 代表的成本比现任的多。

所以问题很简单:执行此比较的正确方法是什么?我考虑过 :cost => BigDecimal.new(candidate.cost.to_s, 18),但这感觉不对——例如,数字 18 从何而来?

最佳答案

尝试使用 BigDecimal#round:

def load_bill_unless_exists(candidate)
incumbents = Bill.scoped.where(:cost => candidate.cost.round(5))
candidate.save unless incumbents.exists?
end

来自文档:

Round to the nearest 1 (by default), returning the result as a BigDecimal. If n is specified and positive, the fractional part of the result has no more than that many digits.

鉴于您在架构中指定了 5 的精度,这就是您在进行比较时应该四舍五入的精度。

关于ruby-on-rails - 如何比较 BigDecimal 与 ActiveRecord 小数字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6297230/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com