1

それぞれUserにたくさんありPurchasesます。過去 28 日間の合計を求めたいと思います。

t1 = Time.now - (28.days)
t2 = Time.now
@dailysum = Array.new(29)
(0..29).each do |i|
  @dailysum[i] = @user.purchases.where(:created_at => (Time.now-(i.day))..(Time.now-((i-1).days))).sum(:amount)
end

これは機能しますが、これについてはもっと良い方法があると確信しています。助言がありますか?

4

3 に答える 3

2

:groupsumにオプションを渡す必要があります。オプションの値は、:groupデータベースによって異なります。pg と mysql のバージョンを提供します。

# purchases.rb
def self.recent(num)
  where('created_at > ?', num.days.ago
end

# PG version
@user.purchases.recent.sum(:amount, group: "DATE_PART('year', purchases.created_at) || '-' || DATE_PART('month', purchases.created_at) || '-' || DATE_PART('day', purchases.created_at)")

# mysql version
@user.purchases.recent.sum(:amount, group: "DATE(purchases.created_at)")

これは、キーが日付で、値が購入の合計であるハッシュになります。

これにより、過去 28 日間の毎日のクエリと比較して、クエリが 27 回少なくなります。

于 2013-02-06T10:58:45.430 に答える
2

/!\ 他の (より良い) 回答を見る

この回答は、過去 28 日間の購入の合計を計算します

過去28日間の合計の計算については、私の他の回答を読んでください

興味のある人のために、これをオンラインで保管しています。


@user.purchases
    .where('created_at > ?', 28.days.ago) # retrieve all purchases within the last 28 days
    .sum(:amount)                         # get the sum of the amount column

@andy によって提案されたスコープを使用する場合:

# in purchase.rb
scope :recent, ->(d) { where('created_at > ?', d.days.ago) }

# then in you controller
@user.purchases
  .recent(28)          # retrieve all purchases within the last 28 days
  .sum(:amount)        # get the sum of the amount column
于 2013-02-06T11:14:51.940 に答える
0

質問をよりよく理解したので、ここで 2 回目の試行を行います。

これを文脈から外して行うのは難しいです。

user.purchases
  .where('created_at > ?', 28.days.ago)
  .group_by { |p| p.created_at.to_date }
  .collect { |d, ps| [d, ps.sum { |p| p.amount }]  }

これにより、日付とこの日付の合計金額を含む配列の配列が返されます。

[
  ["Mon, 28 Jan 2013", 137],
  ["Tue, 29 Jan 2013", 49]
  ["Wed, 30 Jan 2013", 237]
]
于 2013-02-06T14:20:55.820 に答える