diff --git a/app/models/reaction.rb b/app/models/reaction.rb index 35284d162..8926f25e7 100644 --- a/app/models/reaction.rb +++ b/app/models/reaction.rb @@ -21,9 +21,9 @@ class Reaction < ApplicationRecord validate :permissions before_save :assign_points - after_commit :async_bust, :bust_reactable_cache + after_commit :async_bust, :bust_reactable_cache, :update_reactable after_save :index_to_algolia - after_save :update_reactable, :touch_user + after_save :touch_user before_destroy :update_reactable_without_delay, unless: :destroyed_by_association before_destroy :bust_reactable_cache_without_delay before_destroy :remove_algolia @@ -80,7 +80,7 @@ class Reaction < ApplicationRecord end def update_reactable - Reactions::UpdateReactableJob.perform_later(id) + Reactions::UpdateReactableWorker.perform_async(id) end def bust_reactable_cache @@ -96,7 +96,7 @@ class Reaction < ApplicationRecord end def update_reactable_without_delay - Reactions::UpdateReactableJob.perform_now(id) + Reactions::UpdateReactableWorker.new.perform(id) end def reading_time diff --git a/app/workers/reactions/update_reactable_worker.rb b/app/workers/reactions/update_reactable_worker.rb new file mode 100644 index 000000000..52312042b --- /dev/null +++ b/app/workers/reactions/update_reactable_worker.rb @@ -0,0 +1,15 @@ +module Reactions + class UpdateReactableWorker + include Sidekiq::Worker + + sidekiq_options queue: :high_priority, retry: 10 + + def perform(reaction_id) + reaction = Reaction.find_by(id: reaction_id) + return unless reaction&.reactable + + reaction.reactable.touch_by_reaction if reaction.reactable.respond_to?(:touch_by_reaction) + reaction.reactable.sync_reactions_count if rand(6) == 1 && reaction.reactable.respond_to?(:sync_reactions_count) + end + end +end diff --git a/spec/models/reaction_spec.rb b/spec/models/reaction_spec.rb index e1843168d..8c1fa45af 100644 --- a/spec/models/reaction_spec.rb +++ b/spec/models/reaction_spec.rb @@ -114,14 +114,6 @@ RSpec.describe Reaction, type: :model do context "when callbacks are called after save" do let!(:reaction) { build(:reaction, category: "like", reactable: article, user: user) } - it "enqueues the correct jobs" do - expect do - reaction.save - end.to( - have_enqueued_job(Reactions::UpdateReactableJob).exactly(:once), - ) - end - describe "enqueues the correct worker" do it "BustReactableCacheWorker" do sidekiq_assert_enqueued_with(job: Reactions::BustReactableCacheWorker) do diff --git a/spec/workers/reactions/update_reactable_worker_spec.rb b/spec/workers/reactions/update_reactable_worker_spec.rb new file mode 100644 index 000000000..60d74aa62 --- /dev/null +++ b/spec/workers/reactions/update_reactable_worker_spec.rb @@ -0,0 +1,30 @@ +require "rails_helper" + +RSpec.describe Reactions::UpdateReactableWorker, type: :worker do + describe "#perform" do + let(:article) { create(:article) } + let(:reaction) { create(:reaction, reactable: article) } + let(:comment) { create(:comment, commentable: article) } + let(:comment_reaction) { create(:reaction, reactable: comment) } + let(:worker) { subject } + + it " updates the reactable Article" do + sidekiq_assert_enqueued_with(job: Articles::ScoreCalcWorker) do + worker.perform(reaction.id) + end + end + + it " updates the reactable Comment" do + updated_at = 1.day.ago + comment.update_columns(updated_at: updated_at) + worker.perform(comment_reaction.id) + expect(comment.reload.updated_at).to be > updated_at + end + + it " doesn't fail if a reaction doesn't exist" do + expect do + worker.perform(Reaction.maximum(:id).to_i + 1) + end. not_to raise_error + end + end +end