按周/月/等分组和ActiveRecord?

tei*_*ich 35 activerecord grouping ruby-on-rails

我在我的产品中做了一些静力学计算.用户已经执行了许多操作,比方说发布了评论.我希望能够向他们展示他们在过去一个月或过去一年中每个月每周发布的评论数量.

有没有办法用activerecord这种方式分组?我最好只是手动执行此操作 - 根据我自己的标准迭代记录总结?

class User < ActiveRecord::Base
  has_many :comments
end

class Comments < ActiveRecord::Base
  belongs_to :user
end

@user.comments(:all).map {|c| ...do my calculations here...}
Run Code Online (Sandbox Code Playgroud)

或者有更好的方法吗?

谢谢!奥伦

Woj*_*ski 82

在Postgres中你可以做到:

@user.comments.group("DATE_TRUNC('month', created_at)").count
Run Code Online (Sandbox Code Playgroud)

要得到:

{"2012-08-01 00:00:00"=>152, "2012-07-01 00:00:00"=>57, "2012-09-01 00:00:00"=>132}
Run Code Online (Sandbox Code Playgroud)

它接受从"微秒"到"千禧年"的值进行分组:http: //www.postgresql.org/docs/8.1/static/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC

  • 比使用ruby可枚举的group_by快得多! (4认同)

tei*_*ich 31

在这种情况下,对我来说最好的解决方案是在直接SQL中执行,或者使用Ruby group_by函数:

@user.all.group_by{ |u| u.created_at.beginning_of_month }
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这将加载数据库中的所有记录,实例化ActiveRecord对象,将日期解析为ActiveSupport的时区感知对象 - 所有这些只是为了计算记录数. (14认同)
  • `group_by`不是ActiveRecord方法,而是`Enumerable`上的Ruby方法. (12认同)
  • 这是一个不好的做法,因为当你使用.all时,它会获得数据库中的所有记录,这将花费你太多 (2认同)
  • 多么浪费内存啊!使用@WojtekKruszewski解决方案:`@user.comments.group("DATE_TRUNC('month',created_at)").count` (2认同)

Ahm*_*ain 22

这是更精致的版本

@user.comments.group("year(created_at)").group("month(created_at)").count
Run Code Online (Sandbox Code Playgroud)


Mik*_*ffe 13

我的猜测是这样的:

@user.comments.count(:group => "year(created_at),month(created_at)")
Run Code Online (Sandbox Code Playgroud)

干码,ymmv

  • 这似乎是mysql特有的 (2认同)