diff --git a/app/models/user.rb b/app/models/user.rb index 62604333f76..47b994997e5 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -235,23 +235,51 @@ class User < ActiveRecord::Base User.email_hash(email) end - def unread_notifications_by_type - @unread_notifications_by_type ||= notifications.visible.where("id > ? and read = false", seen_notification_id).group(:notification_type).count - end - def reload - @unread_notifications_by_type = nil + @unread_notifications = nil @unread_total_notifications = nil @unread_pms = nil super end def unread_private_messages - @unread_pms ||= notifications.visible.where("read = false AND notification_type = ?", Notification.types[:private_message]).count + @unread_pms ||= + begin + # perf critical, much more efficient than AR + sql = " + SELECT COUNT(*) FROM notifications n + LEFT JOIN topics t ON n.topic_id = t.id + WHERE + t.deleted_at IS NULL AND + n.notification_type = :type AND + n.user_id = :user_id AND + NOT read" + + User.exec_sql(sql, user_id: id, + type: Notification.types[:private_message]) + .getvalue(0,0).to_i + end end def unread_notifications - unread_notifications_by_type.except(Notification.types[:private_message]).values.sum + @unread_notifications ||= + begin + # perf critical, much more efficient than AR + sql = " + SELECT COUNT(*) FROM notifications n + LEFT JOIN topics t ON n.topic_id = t.id + WHERE + t.deleted_at IS NULL AND + n.notification_type <> :pm AND + n.user_id = :user_id AND + NOT read AND + n.id > :seen_notification_id" + + User.exec_sql(sql, user_id: id, + seen_notification_id: seen_notification_id, + pm: Notification.types[:private_message]) + .getvalue(0,0).to_i + end end def total_unread_notifications diff --git a/spec/models/post_timing_spec.rb b/spec/models/post_timing_spec.rb index b2c18dd8045..002ba5729c3 100644 --- a/spec/models/post_timing_spec.rb +++ b/spec/models/post_timing_spec.rb @@ -90,12 +90,10 @@ describe PostTiming do PostAction.act(user2, post, PostActionType.types[:like]) expect(post.user.unread_notifications).to eq(1) - expect(post.user.unread_notifications_by_type).to eq({Notification.types[:liked] => 1 }) PostTiming.process_timings(post.user, post.topic_id, 1, [[post.post_number, 100]]) post.user.reload - expect(post.user.unread_notifications_by_type).to eq({}) expect(post.user.unread_notifications).to eq(0) end