在给定的月份中按天获取“created_at”元素的数量

我想在我的应用程序中创建一个过去一个月创建的用户的简单图表。 就像过去一个月中的每一天一样,我想显示当天注册的用户数。 到目前为止我所拥有的:

# Controller @users = User.count(:order => 'DATE(created_at) DESC', :group => ["DATE(created_at)"]) # View  
# Output 2010-01-10 2 2010-01-08 11 2010-01-07 23 2010-01-02 4

哪个是好的,但是如果在某一天没有创建用户,则应该说“0”而不是根本不存在。 如何在过去30天内遍历每一天并显示当天创建的用户数?

我认为分离胜过最小的性能提升:

 # Controller @users = User.all(:conditions => ["created_at >= ?", Date.today.at_beginning_of_month]) # View Date.today.at_beginning_of_month.upto(Date.today).each do |date| <%= date %>: <%= @users.select{|u| u.created_at == date }.size %> end 
 date = Date.today-30 # Controller @users = User.count(:conditions=>["created_at >= ?", date], :order => 'DATE(created_at) DESC', :group => ["DATE(created_at)"]) date.upto(Date.today) do |x| @users[x.to_s] ||= 0 end @users.sort! # View <% @users.each do |user| %> <%= user[0] %>
<%= user[1] %> <% end %>

正如@floyd先前评论的那样,执行SELECT的代码属于模型:

 class User < ActiveRecord::Base def self.count_new_users_per_day(cutoff_at) result = count(:all, :conditions => ["created_at >= ?", cutoff_at], :group => "DATE(created_at)") # See http://ruby-doc.org/core-1.8.7/classes/Hash.html#M000163 result.default = 0 result end end 

控制器执行逻辑并调用模型层:

 class UsersController < ActionController::Base def index @cutoff_at = 30.days.ago.at_midnight @new_users_by_date = User.count_new_users_per_day(@cutoff_at) @dates = ((@cutoff_at.to_date) .. (@cutoff_at.to_date >> 1)) end end 

视图仅负责显示控制器为其设置的数据:

 # Chose to move the code to a partial <%= render :partial => "user_count", :collection => @dates, :as => :date %> # _user_count.html.erb <%=h date.to_s(:db) %> <%= number_with_delimiter(@new_users_by_date[date.to_s(:db)]) %> 

基本上,由于SQL不会返回缺少的日期,因此您必须自己迭代完整的日期集,并询问Hash / ResultSet是否具有正确的值。 在上面的模型实现中,我在事后设置了Hash的默认值,给我一个干净的方法,在缺少值时获得零。