Skip to content

Commit 3e0d221

Browse files
committed
cache aggregated word counts on worldbuilding pages
1 parent c312d43 commit 3e0d221

File tree

9 files changed

+84
-3
lines changed

9 files changed

+84
-3
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class CacheSumAttributeWordCountJob < ApplicationJob
2+
queue_as :cache
3+
4+
def perform(*args)
5+
entity_type = args.shift
6+
entity_id = args.shift
7+
8+
entity = entity_type.constantize.find_by(id: entity_id)
9+
sum_attribute_word_count = Attribute.where(entity_type: entity_type, entity_id: entity_id).sum(:word_count_cache)
10+
11+
update = entity.word_count_updates.find_or_initialize_by(
12+
for_date: DateTime.current,
13+
)
14+
update.word_count = sum_attribute_word_count
15+
update.user_id ||= entity.user_id
16+
17+
update.save!
18+
end
19+
end

app/models/concerns/is_content_page.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ module IsContentPage
1818
has_many :timeline_events, through: :timeline_event_entities
1919
has_many :timelines, -> { distinct }, through: :timeline_events
2020

21+
has_many :word_count_updates, as: :entity, dependent: :destroy
22+
def latest_word_count_cache
23+
word_count_updates.order('for_date DESC').limit(1).first.try(:word_count) || 0
24+
end
25+
2126
scope :unarchived, -> { where(archived_at: nil) }
2227
def archive!
2328
update!(archived_at: DateTime.now)

app/models/page_data/attribute.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@ class Attribute < ApplicationRecord
2020
end
2121

2222
after_commit do
23-
CacheAttributeWordCountJob.perform_later(self.id) if saved_changes.key?('value')
23+
if saved_changes.key?('value')
24+
# Cache the updated word count on this attribute
25+
CacheAttributeWordCountJob.perform_later(self.id)
26+
27+
# Cache the updated word count on the page this attribute belongs to
28+
CacheSumAttributeWordCountJob.perform_later(self.entity_type, self.entity_id)
29+
end
2430
end
2531

2632
after_save do

app/models/word_count_update.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class WordCountUpdate < ApplicationRecord
2+
belongs_to :user
3+
belongs_to :entity, polymorphic: true
4+
end
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class CreateWordCountUpdates < ActiveRecord::Migration[6.0]
2+
def change
3+
create_table :word_count_updates do |t|
4+
t.references :user, null: false, foreign_key: true
5+
t.references :entity, polymorphic: true, null: false
6+
t.integer :word_count
7+
t.date :for_date
8+
9+
t.timestamps
10+
end
11+
end
12+
end

db/schema.rb

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema.define(version: 2021_10_07_215520) do
13+
ActiveRecord::Schema.define(version: 2021_10_07_234707) do
1414

1515
create_table "active_storage_attachments", force: :cascade do |t|
1616
t.string "name", null: false
@@ -3637,6 +3637,18 @@
36373637
t.integer "habitat_id"
36383638
end
36393639

3640+
create_table "word_count_updates", force: :cascade do |t|
3641+
t.integer "user_id", null: false
3642+
t.string "entity_type", null: false
3643+
t.integer "entity_id", null: false
3644+
t.integer "word_count"
3645+
t.date "for_date"
3646+
t.datetime "created_at", precision: 6, null: false
3647+
t.datetime "updated_at", precision: 6, null: false
3648+
t.index ["entity_type", "entity_id"], name: "index_word_count_updates_on_entity_type_and_entity_id"
3649+
t.index ["user_id"], name: "index_word_count_updates_on_user_id"
3650+
end
3651+
36403652
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
36413653
add_foreign_key "api_keys", "users"
36423654
add_foreign_key "api_requests", "application_integrations"
@@ -4048,4 +4060,5 @@
40484060
add_foreign_key "vehicles", "users"
40494061
add_foreign_key "votes", "users"
40504062
add_foreign_key "votes", "votables"
4063+
add_foreign_key "word_count_updates", "users"
40514064
end

lib/tasks/backfill.rake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
namespace :backfill do
22
desc "Backfill cached word counts on all attributes"
33
task attribute_word_count_caches: :environment do
4-
Attribute.where(cached_word_count: nil).find_each do |attribute|
4+
Attribute.where(word_count_cache: nil).where.not(value: ["", " ", ".", nil]).find_each do |attribute|
55
word_count = WordCountAnalyzer::Counter.new(
66
ellipsis: 'no_special_treatment',
77
hyperlink: 'count_as_one',
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2+
3+
one:
4+
user: one
5+
entity: one
6+
entity_type: Entity
7+
word_count: 1
8+
for_date: 2021-10-07
9+
10+
two:
11+
user: two
12+
entity: two
13+
entity_type: Entity
14+
word_count: 1
15+
for_date: 2021-10-07
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
require 'test_helper'
2+
3+
class WordCountUpdateTest < ActiveSupport::TestCase
4+
# test "the truth" do
5+
# assert true
6+
# end
7+
end

0 commit comments

Comments
 (0)