Caching sum privileged reaction scores (#15299)
* Caching sum privileged reaction scores This relates to work on improving the feed. Namely that in the current proposal in PR #15240 I'm not accounting for how privileged users have given feedback on an article. With this change, I will now have a cached value on the articles table that can be a proxy for how the privileged users have reacted. In addition there's a small refactor that moves a constant to the correct scoping object. Dependent on #15283. * Fixing method name to `exists?` Prior to this commit, I was using `exist?` which doesn't work for ActiveRecord::Relation objects.
This commit is contained in:
parent
bff7cd1118
commit
95969eb973
6 changed files with 51 additions and 3 deletions
|
|
@ -2,12 +2,10 @@ module Admin
|
|||
class PrivilegedReactionsController < Admin::ApplicationController
|
||||
layout "admin"
|
||||
|
||||
PRIVILEGED_REACTION_CATEGORIES = %i[thumbsup thumbsdown vomit].freeze
|
||||
|
||||
def index
|
||||
@q = Reaction
|
||||
.includes(:user, :reactable)
|
||||
.where(category: PRIVILEGED_REACTION_CATEGORIES)
|
||||
.privileged_category
|
||||
.order(created_at: :desc)
|
||||
.ransack(params[:q])
|
||||
@privileged_reactions = @q.result.page(params[:page] || 1).per(25)
|
||||
|
|
|
|||
|
|
@ -460,6 +460,7 @@ class Article < ApplicationRecord
|
|||
def update_score
|
||||
self.score = reactions.sum(:points) + Reaction.where(reactable_id: user_id, reactable_type: "User").sum(:points)
|
||||
update_columns(score: score,
|
||||
privileged_users_reaction_points_sum: reactions.privileged_category.sum(:points),
|
||||
comment_score: comments.sum(:score),
|
||||
hotness_score: BlackBox.article_hotness_score(self),
|
||||
spaminess_rating: BlackBox.calculate_spaminess(self))
|
||||
|
|
|
|||
|
|
@ -5,8 +5,14 @@ class Reaction < ApplicationRecord
|
|||
"thumbsdown" => -10.0
|
||||
}.freeze
|
||||
|
||||
# The union of public and privileged categories
|
||||
CATEGORIES = %w[like readinglist unicorn thinking hands thumbsup thumbsdown vomit].freeze
|
||||
|
||||
# These are the general category of reactions that anyone can choose
|
||||
PUBLIC_CATEGORIES = %w[like readinglist unicorn thinking hands].freeze
|
||||
|
||||
# These are categories of reactions that administrators can select
|
||||
PRIVILEGED_CATEGORIES = %w[thumbsup thumbsdown vomit].freeze
|
||||
REACTABLE_TYPES = %w[Comment Article User].freeze
|
||||
STATUSES = %w[valid invalid confirmed archived].freeze
|
||||
|
||||
|
|
@ -31,6 +37,7 @@ class Reaction < ApplicationRecord
|
|||
.or(comment_vomits.where(reactable_id: user.comment_ids))
|
||||
.or(user_vomits.where(user_id: user.id))
|
||||
}
|
||||
scope :privileged_category, -> { where(category: PRIVILEGED_CATEGORIES) }
|
||||
|
||||
validates :category, inclusion: { in: CATEGORIES }
|
||||
validates :reactable_type, inclusion: { in: REACTABLE_TYPES }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
module DataUpdateScripts
|
||||
class UpdateEachArticlesPrivilegedUserPointCount
|
||||
def run
|
||||
# This code is "idempotent" in that it's calculating and caching a value stored elsewhere.
|
||||
Article.find_in_batches do |articles|
|
||||
articles.each do |article|
|
||||
# Given that we have a default of 0, don't update if we
|
||||
# don't have any reactions.
|
||||
next unless article.reactions.privileged_category.exists?
|
||||
|
||||
article.update_column(:privileged_users_reaction_points_sum,
|
||||
article.reactions.privileged_category.sum(:points))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
require "rails_helper"
|
||||
require Rails.root.join(
|
||||
"lib/data_update_scripts/20211104200856_update_each_articles_privileged_user_point_count.rb",
|
||||
)
|
||||
|
||||
describe DataUpdateScripts::UpdateEachArticlesPrivilegedUserPointCount do
|
||||
it "updates articles scores" do
|
||||
article = create(:article)
|
||||
user = create(:user, :trusted)
|
||||
reaction = create(:thumbsdown_reaction, user: user, reactable: article)
|
||||
|
||||
# Short-circuiting callbacks
|
||||
reaction.update_column(:points, 1_000_000)
|
||||
|
||||
expect { described_class.new.run }.to change { article.reload.privileged_users_reaction_points_sum }.to(1_000_000)
|
||||
end
|
||||
end
|
||||
|
|
@ -1331,6 +1331,14 @@ RSpec.describe Article, type: :model do
|
|||
article.update_score
|
||||
expect { article.update_score }.not_to change { article.reload.hotness_score }
|
||||
end
|
||||
|
||||
it "caches the privileged score values" do
|
||||
user = create(:user, :trusted)
|
||||
|
||||
create(:thumbsdown_reaction, reactable: article, user: user)
|
||||
|
||||
expect { article.update_score }.to change { article.reload.privileged_users_reaction_points_sum }
|
||||
end
|
||||
end
|
||||
|
||||
describe "#feed_source_url and canonical_url must be unique for published articles" do
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue