Getting count of elements by `created_at` by day in a given month

前端 未结 3 1949
深忆病人
深忆病人 2021-01-13 19:28

I wanted to make a simple chart of users that have been created in the past month in my app. Like basically for each day in the past month I want to show the count of users

相关标签:
3条回答
  • 2021-01-13 20:02
    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] %><br />
      <%= user[1] %>
    <% end %>
    
    0 讨论(0)
  • 2021-01-13 20:10

    I think separation trumps the minimal performance gains here:

    # 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
    
    0 讨论(0)
  • 2021-01-13 20:11

    As @floyd commented on earlier, the code to do the SELECT belongs in the model:

    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
    

    The controller does logic and calls into the model layer:

    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
    

    And the view is only responsible for displaying the data the controller's setup for it:

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

    Basically, since SQL won't return missing dates, you have to iterate over the full set of dates yourself, and ask the Hash/ResultSet if it has the correct value. In the model implementation above, I set the Hash's default value after the fact, giving me a clean way to get a zero when a value is missing.

    0 讨论(0)
提交回复
热议问题