我有一个应用程序,我正在尝试将一个美元金额生成一个名为Metric的新AR记录。我编写了以下简单类方法来生成新的度量方法:
def self.last_year
m = Metric.new
m.name = Figaro.env.company_name
m.metric_type = "Last Year"
m.amount = ActiveRecord::Base.connection.execute("select sum(dst_amt::DECIMAL) from distributions where dst_code like 'COL%' and dst_posted_date::DATE BETWEEN (select (date_trunc('month', current_date)) - INTERVAL '13 Month') and (select (date_trunc('month', current_date)) - INTERVAL '366 Day')")
m.save
end
这基本上可以工作并创建度量标准记录,但是在运行此方法后在控制台中输出它的数量是:
<BigDecimal:10173c470,'0.0',9(18)>
当我在Postico或Navicat raw中运行SQL时,结果的数字为:1043.88
。所以我的问题是:
1。)基于此查询和原始结果,我应该在postgres中使用哪个数据类型的金额字段?我尝试了十进制,但它将输出写为BigDecimal,我无法读取它,我也尝试了浮点数,但是当我运行类方法时,它在类上给了我一个NoMethodError to_f
。
2。)这是从类中运行SQL的最佳方法吗?当我通过Navicat或Postico运行它时,我的SQL是正确的,但是在类I中输出一个大的十进制数。
我的最终目标是在多个服务器上生成度量标准记录,然后通过第二个dbase连接以某种方式将它们转移到目标服务器,或者只是导出到csv,scp over,并通过目标服务器上的csv导入。实际上这应该是一种API类型的场景,但我没有那种时间,并且需要在今天获得有用的东西。
如果我的代码和/或问题不明确,请告诉我,我会进行修改。
更新 因此,当我尝试在控制台中打破此方法时,我运行它:
a = ActiveRecord::Base.connection.execute("select sum(dst_amt::DECIMAL) from distributions where dst_code like 'COL%' and dst_posted_date::DATE BETWEEN (select (date_trunc('month', current_date)) - INTERVAL '13 Month') and (select (date_trunc('month', current_date)) - INTERVAL '366 Day')")
这给了我:=> #<PG::Result:0x0000010d84c958 status=PGRES_TUPLES_OK ntuples=1 nfields=1 cmd_tuples=1>
然后从控制台我调用a[0]
我得到哈希值=> {"sum"=>"1101.88"}
所以我想我的问题已经扩大了。我是否正确地调用SQL来填充方法中的金额字段?如果是这样,我如何解析此输出以将十进制值1101.88(或任何结果)返回到作为十进制类型字段的金额列?
再次更新
这是我的重构方法
def self.last_year_mtd
m = Metric.new
m.name = Figaro.env.company_name
m.metric_type = "Last Year MTD"
sql = ActiveRecord::Base.connection.execute("select sum(dst_amt::DECIMAL) from distributions where dst_code like 'COL%' and dst_posted_date::DATE BETWEEN (select (date_trunc('month', current_date)) - INTERVAL '13 Month') and (select (date_trunc('month', current_date)) - INTERVAL '366 Day')")
total = sql[0]["sum"].to_s
m.amount = total
m.save
end
因此,当我从控制台运行它时,它会创建一个新的Metric记录。因此,如果我创建两个记录,我需要对其进行算术运算。所以我试了一下。
从控制台中调出last_year_mtd
和类似的方法,它具有不同的查询并生成不同的大小数。
然后我指定a = Metric.first
和b = Metric.last
来获取两个不同的对象。
然后我做算术:2.1.1 :012 > (b.amount - a.amount).to_s
=> "1396.4"
这看起来很有效。在算术上调用.to_s
似乎已经成功了。
我确信这种方法可以更干净,所以如果有人对重构有想法,我会非常感激。
答案 0 :(得分:1)
使用小数。
如果需要显示该值,则使用to_s将其转换为字符串,或使用to_f将其转换为float。但是有些小数不能准确地表示为浮点数,如果你想要做的只是查看值,那么字符串表示是合适的。