在我的应用用户中注册属于流的事件。注册在注册模型中进行管理,该模型有一个名为“参加”的布尔字段。
我正在尝试生成排行榜并需要知道:每个用户的注册总数,以及每个单独事件流中用户注册的计数。
我正在尝试这个(在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硬编码(它们相当固定)到User表中,只要注册模型保存上的有人参与属性发生更改,就会手动更新。
但是,我真的很好奇如何执行这样的查询。在计算有关系的记录的统计数据和报告时,它必须始终出现。
非常感谢您的时间和考虑。提前谢谢。
答案 0 :(得分:6)
首先,作为样式和轨道功能的几点,可以帮助您构建数据库查询。
1)你最好把它写成范围而不是方法,即
scope attendance_counts, select("users.*, sum(attended) as attendance_count").joins(:registrations).group('registrations.user_id').order('attendance_count DESC')
2)最好不要在你构建的查询中调用all / find / first,直到你真正需要它(即在控制器或视图中)。这样,如果您决定在以后对数据库查询实施操作/片段缓存,则在向用户提供缓存的操作/片段时将不会调用它。
3)Rails有一系列功能来帮助聚合数据库数据。例如,如果您只想要用户的ID和有人参与的总和,您可以使用类似下面的代码:
Registrations.group(:user_id).sum(:attended)
其他功能包括count
,avg
,minimum
,maximum
最后,在回答您的问题时,rails将为您创建一个属性,以便您访问查询的选择部分中的任何自定义字段的值。 e.g。
@users = User.attendance_counts
@users[0].attendance_count # The attendance count for the first user returned by the query