这样的方法最好在您的模型中定义并在您的视图中执行。控制器实际上只是用来设置一些东西,以便视图可以完成它的工作。
在模型中定义这些的好处是您可以为它们编写单元测试,这通常比功能或集成测试更容易设置。您的方法也很容易从console 命令行进行测试。
对于很多事情,您可以简单地使用sum 方法来处理您的人际关系。它可能看起来像这样:
user.activities.sum(:time_spent)
您可以将范围应用于activities 关系以更好地定位结果。
更新
要按不同的参数组合在一起,您始终可以将其表示为 SQL 连接并提取计算值。查询看起来像这样:
SELECT users.id, projects.internal, SUM(activities.time) AS total_time, activities.on_date
FROM users
LEFT JOIN projects ON projects.user_id=users.id
LEFT JOIN activities ON activities.project_id=projects.id
GROUP BY users.id, projects.internal, activities.on_date
一旦正确设置,根据需要调整列名,您可以将其包装在一个调用中,这样可以轻松提取值:
class User < ActiveRecord::Base
def self.time_spent_on_projects(user_id = nil)
query = "..." # Query from above
# Allow scoping to a particular user by adding a WHERE clause
query = self.sanitize_sql([ "#{query} WHERE users.id=?", user_id ])
self.connection.select_all(query)
end
def time_spent_on_projects
self.class.time_spent_on_projects(self.id)
end
end
这会将所有值返回为String 或nil,因此您可能需要根据需要转换为数字。