レポート/メトリクス ページで作業しており、クエリをできる限り最適化する必要があるため、効率のために find_by_sql を使用しています。
私のクエリの 1 つは、カウントといくつかの合計を返す集計関数を実行しています。このクエリの結果をモデルのインスタンス変数に割り当てています。
動作するコードがありますが、コードが怖いです。使用されているメソッドに関する 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 は常に行を返します (null 値ですが、有効な行)。.first
ただし、返された配列を呼び出すべきではない理由はありますか?[].first => nil
予想外の場合にぶつかるのが怖いです。- メソッドを使用して結果を「キャッシュ」する私の方法は
stats
、DB を 1 回だけクエリする適切な方法ですか? 集計データを取得するためだけに、多くのコードとメソッドが必要になるようです。