diff --git a/app/models/chapter.rb b/app/models/chapter.rb index 893dade0ee7..ffbd0baea1c 100644 --- a/app/models/chapter.rb +++ b/app/models/chapter.rb @@ -5,11 +5,13 @@ class Chapter < ApplicationRecord include WorkChapterCountCaching include CreationNotifier include Creatable + include Responder belongs_to :work, inverse_of: :chapters # acts_as_list scope: 'work_id = #{work_id}' acts_as_commentable + has_many :comments, as: :commentable # Handled in #delete_all_comments validates_length_of :title, allow_blank: true, maximum: ArchiveConfig.TITLE_MAX, too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.TITLE_MAX) @@ -50,7 +52,13 @@ def inherit_creatorships scope :in_order, -> { order(:position) } scope :posted, -> { where(posted: true) } + before_destroy :fix_positions_before_destroy, :invalidate_chapter_count, :delete_all_comments + after_destroy :update_work_stats + after_save :fix_positions + after_save :invalidate_chapter_count, if: proc { |chapter| chapter.saved_change_to_posted? } + after_commit :update_series_index + def fix_positions if work&.persisted? positions_changed = false @@ -76,10 +84,6 @@ def fix_positions end end - after_save :invalidate_chapter_count, - if: Proc.new { |chapter| chapter.saved_change_to_posted? } - - before_destroy :fix_positions_before_destroy, :invalidate_chapter_count def fix_positions_before_destroy if work&.persisted? && position chapters = work.chapters.where(["position > ?", position]) @@ -87,7 +91,13 @@ def fix_positions_before_destroy end end - after_commit :update_series_index + def delete_all_comments + inbox_comments = InboxComment.where(feedback_comment_id: total_comments.pluck(:id)) + + total_comments.in_batches.delete_all + inbox_comments.in_batches.delete_all + end + def update_series_index return unless work&.series.present? && should_reindex_series? work.serial_works.each(&:update_series_index) diff --git a/app/models/work.rb b/app/models/work.rb index 78919a2ed50..9abc95754b9 100755 --- a/app/models/work.rb +++ b/app/models/work.rb @@ -41,8 +41,9 @@ class Work < ApplicationRecord accepts_nested_attributes_for :challenge_claims acts_as_commentable + has_many :comments, as: :commentable # Handled in chapters#delete_all_comments has_many :total_comments, class_name: 'Comment', through: :chapters - has_many :kudos, as: :commentable, dependent: :destroy + has_many :kudos, as: :commentable, dependent: :delete_all has_many :original_creators, class_name: "WorkOriginalCreator", dependent: :destroy diff --git a/lib/responder.rb b/lib/responder.rb index 4c31ec63ff9..67563df30bf 100644 --- a/lib/responder.rb +++ b/lib/responder.rb @@ -13,9 +13,10 @@ def get_work work = self.commentable elsif self.respond_to?(:bookmarkable) work = self.bookmarkable + elsif self.respond_to?(:work) + work = self.work end work.is_a?(Work) ? work : nil end end - diff --git a/spec/controllers/works/default_rails_actions_spec.rb b/spec/controllers/works/default_rails_actions_spec.rb index 14301cde983..7b50279a6b0 100644 --- a/spec/controllers/works/default_rails_actions_spec.rb +++ b/spec/controllers/works/default_rails_actions_spec.rb @@ -20,7 +20,7 @@ suspended_user.update!(suspended: true, suspended_until: 1.week.from_now) work end - + describe "before_action #clean_work_search_params" do let(:params) { {} } @@ -883,6 +883,8 @@ def call_with_params(params) context "when a work has consecutive deleted comments in a thread" do before do + work.kudos.create(user: create(:user)) # Add a kudo to the work + thread_depth = 4 chapter = work.first_chapter @@ -900,12 +902,35 @@ def call_with_params(params) fake_login_known_user(work.users.first) end - it "deletes the work and redirects to the user's works with a notice" do + it "deletes the work and its associations, and redirects to the user's works with a notice" do delete :destroy, params: { id: work.id } it_redirects_to_with_notice(user_works_path(controller.current_user), "Your work #{work_title} was deleted.") expect { work.reload }.to raise_exception(ActiveRecord::RecordNotFound) + expect(Kudo.count).to eq(0) expect(Comment.count).to eq(0) + expect(InboxComment.count).to eq(0) + end + end + + context "when a work has multiple chapters" do + before do + first_chapter = work.first_chapter + second_chapter = create(:chapter, work: work, position: 2) + + create(:comment, commentable: first_chapter, parent: first_chapter) + create(:comment, commentable: second_chapter, parent: second_chapter) + fake_login_known_user(work.users.first) + end + + it "deletes the work and its associations, and redirects to the user's works with a notice" do + delete :destroy, params: { id: work.id } + + it_redirects_to_with_notice(user_works_path(controller.current_user), "Your work #{work_title} was deleted.") + expect { work.reload } + .to raise_exception(ActiveRecord::RecordNotFound) + expect(Comment.count).to eq(0) + expect(InboxComment.count).to eq(0) end end @@ -917,7 +942,7 @@ def call_with_params(params) it "errors and redirects to user page" do fake_login_known_user(suspended_user) delete :destroy, params: { id: suspended_users_work.id } - + it_redirects_to_simple(user_path(suspended_user)) expect(flash[:error]).to include("Your account has been suspended") end