PERF: Allow preloading 'recent time read' for a user (#9076)
This will be used when serializing multiple user cards
This commit is contained in:
parent
d23f7af3cb
commit
65cc61be7a
|
@ -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?
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue