2011-08-16 38 views
1

在我的应用程序用户寄存器活动,这属于。注册在注册模型中进行管理,该模型具有名为'参加'的布尔字段。Rails3:左连接聚合计数 - 如何计算?

我在尝试生成排行榜并需要知道:每个用户的注册总数以及每个单独事件流中用户注册的数量。

我想这(在User.rb):

# returns an array of users and their attendence count 
def self.attendance_counts 
    User.all( 
     :select => "users.*, sum(attended) as attendance_count", 
     :joins => 'left join `registrations` ON registrations.user_id = users.id', 
     :group => 'registrations.user_id', 
     :order => 'attendance_count DESC' 
    ) 
end 

生成的SQL适用于只是返回总参加数为每个用户,当我在数据库中运行它,但所有的得到恢复是Rails中的用户记录。

我即将放弃并硬编码每个流的counter_cache(它们相当固定)到用户表中,只要在注册模型保存上参加属性更改时手动更新它。

不过,我很好奇如何执行这样的查询。在计算关系记录的统计和报告时,它一定会出现。

你的时间和考虑是非常感谢。提前致谢。

回答

6

首先作为一些关于style和rails函数的点来帮助您构建数据库查询。

1)你更好的写作这是一个范围,而不是即

scope attendance_counts, select("users.*, sum(attended) as attendance_count").joins(:registrations).group('registrations.user_id').order('attendance_count DESC') 

2的方法),这是最好不要打电话给所有的/发现/先上查询,你已经建立了,直到你真正需要它(即在控制器或视图中)。这样,如果您决定稍后实施动作/片段缓存,则在缓存的动作/片段被提供给用户时,将不会调用数据库查询。

3)Rails有一系列函数来帮助汇总db数据。例如,如果你只需要一个用户ID和出席,你可以使用类似下面的代码的总和:在回答

Registrations.group(:user_id).sum(:attended) 

其他功能包括:countavgminimummaximum

最后你的问题,rails将为您创建一个属性,以便访问您在查询的选择部分中具有的任何自定义字段的值。例如

@users = User.attendance_counts 
@users[0].attendance_count # The attendance count for the first user returned by the query 
+0

谢谢各位。我仍然必须使用原始连接sql来获取0(好,空)的记录,但最后一部分通过模型访问自定义字段非常有用。 – manafire