diff --git a/app/models/user.rb b/app/models/user.rb index e8cc35f891c..fd81a979d0a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1211,10 +1211,22 @@ class User < ActiveRecord::Base self.user_emails.secondary.pluck(:email) end + RECENT_TIME_READ_THRESHOLD ||= 60.days + + def self.preload_recent_time_read(users) + times = UserVisit.where(user_id: users.map(&:id)) + .where('visited_at >= ?', RECENT_TIME_READ_THRESHOLD.ago) + .group(:user_id) + .sum(:time_read) + users.each { |u| u.preload_recent_time_read(times[u.id] || 0) } + end + + def preload_recent_time_read(time) + @recent_time_read = time + end + def recent_time_read - self.created_at && self.created_at < 60.days.ago ? - self.user_visits.where('visited_at >= ?', 60.days.ago).sum(:time_read) : - self.user_stat&.time_read + @recent_time_read ||= self.user_visits.where('visited_at >= ?', RECENT_TIME_READ_THRESHOLD.ago).sum(:time_read) end def from_staged? diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index ee1bea598ac..d23451fcfa8 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -2287,4 +2287,32 @@ describe User do expect(user.approved).to eq(true) end end + + describe "#recent_time_read" do + fab!(:user) { Fabricate(:user) } + fab!(:user2) { Fabricate(:user) } + + before_all do + UserVisit.create(user_id: user.id, visited_at: 1.minute.ago, posts_read: 1, mobile: false, time_read: 10) + UserVisit.create(user_id: user.id, visited_at: 2.days.ago, posts_read: 1, mobile: false, time_read: 20) + UserVisit.create(user_id: user.id, visited_at: 1.week.ago, posts_read: 1, mobile: false, time_read: 30) + UserVisit.create(user_id: user.id, visited_at: 1.year.ago, posts_read: 1, mobile: false, time_read: 40) # Old, should be ignored + UserVisit.create(user_id: user2.id, visited_at: 1.minute.ago, posts_read: 1, mobile: false, time_read: 50) + end + + it "calculates correctly" do + expect(user.recent_time_read).to eq(60) + expect(user2.recent_time_read).to eq(50) + end + + it "preloads correctly" do + User.preload_recent_time_read([user, user2]) + + expect(user.instance_variable_get(:@recent_time_read)).to eq(60) + expect(user2.instance_variable_get(:@recent_time_read)).to eq(50) + + expect(user.recent_time_read).to eq(60) + expect(user2.recent_time_read).to eq(50) + end + end end