diff --git a/app/models/user.rb b/app/models/user.rb index b7925553aa4..18553d08d57 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -439,26 +439,36 @@ class User < ActiveRecord::Base # expensive queries MAX_UNREAD_NOTIFICATIONS = 99 + def self.max_unread_notifications + @max_unread_notifications ||= MAX_UNREAD_NOTIFICATIONS + end + + def self.max_unread_notifications=(val) + @max_unread_notifications = val + end + def unread_notifications @unread_notifications ||= begin # perf critical, much more efficient than AR sql = <<~SQL - SELECT COUNT(*) FROM notifications n - LEFT JOIN topics t ON t.id = n.topic_id - WHERE t.deleted_at IS NULL AND - n.notification_type <> :pm AND - n.user_id = :user_id AND - n.id > :seen_notification_id AND - NOT read - LIMIT :limit - + SELECT COUNT(*) FROM ( + SELECT 1 FROM + notifications n + LEFT JOIN topics t ON t.id = n.topic_id + WHERE t.deleted_at IS NULL AND + n.notification_type <> :pm AND + n.user_id = :user_id AND + n.id > :seen_notification_id AND + NOT read + LIMIT :limit + ) AS X SQL DB.query_single(sql, user_id: id, seen_notification_id: seen_notification_id, pm: Notification.types[:private_message], - limit: MAX_UNREAD_NOTIFICATIONS + limit: User.max_unread_notifications )[0].to_i end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 04338ffb6da..42d73ae7073 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1668,6 +1668,26 @@ describe User do end end + describe "#unread_notifications" do + before do + User.max_unread_notifications = 3 + end + + after do + User.max_unread_notifications = nil + end + + it "limits to MAX_UNREAD_NOTIFICATIONS" do + user = Fabricate(:user) + + 4.times do + Notification.create!(user_id: user.id, notification_type: 1, read: false, data: '{}') + end + + expect(user.unread_notifications).to eq(3) + end + end + describe "#unstage" do let!(:staged_user) { Fabricate(:staged, email: 'staged@account.com', active: true, username: 'staged1', name: 'Stage Name') } let(:params) { { email: 'staged@account.com', active: true, username: 'unstaged1', name: 'Foo Bar' } }