我有Users
的模型has_many EventLogs
。
我想创建一个范围,该范围将由具有最多事件日期的人订购用户。
scope :highest_completed_events, .....
如何计算状态为2的EventLog数量,然后对发生此类事件最多的用户进行排序。
User.joins(:event_logs).where("event_logs.status_id = 2")#... COUNT, then ORDER BY
希望这是有道理的。
答案 0 :(得分:3)
这是一个您可以执行的查询,以便根据他们拥有的事件数量来排序您的用户:
@users = User.
select("users.*, COUNT(event_logs.id) as event_logs_count").
joins('LEFT JOIN event_logs ON event_logs.user_id = users.id').
group('users.id').
order('event_logs_count DESC')
您应该使用LEFT JOIN
,因为您希望包含没有任何活动的用户。
如果你把它写成范围:
scope(:highest_completed_events, {
select: 'users.*, COUNT(event_logs.id) as event_logs_count',
joins: 'LEFT JOIN event_logs ON event_logs.user_id = users.id',
group: 'users.id',
order: 'event_logs_count DESC'
})
@users = User.highest_completed_events
要按特定状态过滤事件,只需使用where()
即可。
@users = User.
select("users.*, COUNT(event_logs.id) as event_logs_count").
joins('LEFT JOIN event_logs ON event_logs.user_id = users.id').
where('event_logs.status = ?', STATUS_COMPLETE).
group('users.id').
order('event_logs_count DESC')
顺便说一句,有时候你会遇到问题,ActiveRecord会在做select()
这样的事情时剥离你的自定义@users.count
语句。我通常做的是将这种东西嵌入自定义的from()
语句中。
_from = User.
select("users.*, COUNT(event_logs.id) as event_logs_count").
joins('LEFT JOIN event_logs ON event_logs.user_id = users.id').
group('users.id').
order('event_logs_count DESC').to_sql
@users = User.from("(#{_from}) as users")
@users.count # will work
答案 1 :(得分:1)
尝试:
User.all.sort_by{|u| u.event_logs.select{|l| l.status_id = 2}.count}.reverse
还是'事件日志'?你的行不应该是has_many :event_logs
吗?