Как прокомментировал @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 по умолчанию после факта, предоставляя мне чистый способ получить ноль при отсутствии значения.