假设有这样一个模式:
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从哪里来?