在报告/指标页面上工作,我需要尽可能优化查询,因此我使用 find_by_sql 来提高效率。
我的一个查询是做一些聚合函数,我返回一个计数和一些总和。我将此查询的结果分配给模型的实例变量。
我有工作代码,但代码让我害怕。我已经阅读了有关使用方法的官方 Ruby/Rails 文档,但我仍然认为我正在做的事情有问题。
def initialize(args)
@loans_count = stats.loans_count
@total_fees_in_cents = stats.total_fees_in_cents
@total_amount_in_cents = stats.total_amount_in_cents
end
def stats
@stats ||= find_stats
end
def find_stats
if single_year?
loans = Loan.find_by_sql(["SELECT count(*) as loans_count, sum(amount) as total_amount_in_cents, sum(fee) as total_fees_in_cents FROM loans WHERE account_id = ? AND year = ? LIMIT 1", @account_id, @year]).first
else
loans = Loan.find_by_sql(["SELECT count(*) as loans_count, sum(amount) as total_amount_in_cents, sum(fee) as total_fees_in_cents FROM loans WHERE account_id = ? LIMIT 1", @account_id]).first
end
# Store results in OpenStruct for ease of access later on
OpenStruct.new(
loans_count: loans.loans_count || 0,
total_fees_in_cents: loans.total_fees_in_cents || 0,
total_amount_in_cents: loans.total_amount_in_cents || 0
)
end
关注点
find_by_sql
应该返回一个数组;SQL 将始终返回一行,即使没有找到匹配项(空值,但有效行)。但是,有没有理由我不应该调用.first
返回的数组?我害怕[].first => nil
在我没有预料到的情况下被击中。- 我使用该
stats
方法“缓存”结果的方法是仅查询 DB 1 次的适当方法吗?似乎有很多代码和方法只是为了获取一些聚合数据。