わかりました、私は持っています
>> list = Request.find_all_by_artist("someBand")
=> [#<Request id: 1, artist: "someBand", song: "someSong", venue: "Knebworth - Stevenage, United Kingdom", showdate: "2011-07-01", amount: nil, user_id: 2, created_at: "2011-01-01 18:14:08", updated_at: "2011-01-01 18:14:09".............
その後
list.group_by(&:created_at).map {|k,v| [k, v.length]}.sort
=> [[Sat, 01 Jan 2011 18:14:08 UTC +00:00, 10], [Sun, 09 Jan 2011 18:34:19 UTC +00:00, 1], [Sun, 09 Jan 2011 18:38:48 UTC +00:00, 1], [Sun, 09 Jan 2011 18:51:10 UTC +00:00, 1], [Sun, 09 Jan 2011 18:52:30 UTC +00:00, 1], [Thu, 10 Feb 2011 02:22:08 UTC +00:00, 1], [Thu, 10 Feb 2011 20:02:20 UTC +00:00, 1]]
問題は、このようなものではなく、1月9日の日曜日と10日の日曜日がいくつかあることです。
これは私が必要なものです
=> [[Sat, 01 Jan 2011 18:14:08 UTC +00:00, 10], [Sun, 09 Jan 2011 18:34:19 UTC +00:00, 4], [Thu, 10 Feb 2011 20:02:20 UTC +00:00, 2]]
Time
は、グループ化するのに非常に複雑なオブジェクトです。完全なTime
ではなく、作成日でグループ化する場合は、モデルでカスタムメソッドの作成を開始して、グループ基準を返します。
このメソッドは、作成日をおそらく文字列として返す必要があります。
def group_by_criteria
created_at.to_date.to_s(:db)
end
次に、その方法でグループ化します。
list.group_by(&:group_by_criteria).map {|k,v| [k, v.length]}.sort
これははるかにエレガントでシンプルなソリューションだと思います
list.group_by{|x| x.created_at.strftime("%Y-%m-%d")}
そのための宝石があります: groupdate 。
使用法(ドキュメントから):
User.group_by_day(:created_at).count
# {
# 2013-04-16 00:00:00 UTC => 50,
# 2013-04-17 00:00:00 UTC => 100,
# 2013-04-18 00:00:00 UTC => 34
# }
Ipsumの答えは実際には良く、おそらく最良です。
アレルで:
requests = Arel::Table.new(:requests)
query = requests.project("COUNT(*), CAST(requests.created_at AS DATE) as created_at")
query = query.group("CAST (requests.created_at AS DATE)")
Request.find_by_sql(query.to_sql)
mySQLでGROUP BY DATE(created_at)
を使用できます
Rubyコードでこのように使用できます
list.group('DATE(created_at)').map {|k,v| [k, v.length]}.sort
余分な宝石のないグループ:
def self.group_by_day items
data = items.group_by{|x| x.created_at.to_date}
chart_data = {}
data.each do |a,b|
chart_data.merge!({a => b.count})
end
return chart_data
end