Получение количества элементов по методу create_at по дням в данном месяце - PullRequest
4 голосов
/ 11 января 2010

Я хотел сделать простую диаграмму пользователей, которые были созданы в прошлом месяце в моем приложении. Как в основном для каждого дня в прошлом месяце, я хочу показать количество пользователей, которые зарегистрировались в тот день. Что у меня так далеко:

# Controller
@users = User.count(:order => 'DATE(created_at) DESC', :group => ["DATE(created_at)"])

# View
<% @users.each do |user| %>
  <%= user[0] %><br />
  <%= user[1] %>
<% end %>

# Output
2010-01-10 2 
2010-01-08 11
2010-01-07 23
2010-01-02 4

Это нормально, но если в определенный день не было создано ни одного пользователя, оно должно сказать «0», а не отсутствовать вообще. Как я могу просмотреть каждый день за последние 30 дней и показать количество пользователей, созданных в этот день?

Ответы [ 3 ]

8 голосов
/ 11 января 2010
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 %>
4 голосов
/ 11 января 2010

Я думаю, что разделение превосходит минимальный прирост производительности здесь:

# 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
3 голосов
/ 12 января 2010

Как прокомментировал @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
<td><%=h date.to_s(:db) %></td>
<td><%= number_with_delimiter(@new_users_by_date[date.to_s(:db)]) %></td>

По сути, поскольку SQL не будет возвращать пропущенные даты, вам придется самим перебирать весь набор дат и спрашивать Hash / ResultSet, имеет ли оно правильное значение. В приведенной выше реализации модели я установил значение Hash по умолчанию после факта, предоставляя мне чистый способ получить ноль при отсутствии значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...