由於@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的默認值,給了我一個乾淨的方法,以便在缺少值時獲得零。
似乎對我來說看起來太多邏輯了。我認爲操縱屬於控制器 - 預處理似乎比「選擇30次」更好。 – Emily 2010-01-11 20:32:46
select是視圖中唯一的附加邏輯,它可以保存控制器4行。我的首要任務是永遠瘦骨碌的控制器。你對所有的選擇絕對正確,但如果這真的是一個性能問題,我會爲User添加一個方法,將邏輯放在SQL中。類似User.new_accounts_per_day。但是SQL很難。但從來沒有在控制器。 – tfwright 2010-01-11 20:48:24
最多我會在視圖中放入「|| = 0」部分,但肯定會將計數保存在帶有SQL的控制器中。這會給你在控制器中的一行代碼(精簡)和有效的計數。你的實現將是O(@ users.size),並且即使是小型數據集也可能慢100倍。 – klochner 2010-01-11 21:52:24