2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-03-03 23:54:20 +08:00
discourse/app/models/post_revision.rb
Régis Hanol af3cca4462
FIX: Suppress post revision notifications during silent bulk category moves (#37832)
When performing a bulk category move with the "Notify users of this
change" option unchecked, topic authors were still receiving "edited"
notifications. This happened because the silent flag was not propagated
to the PostRevision `after_create` callback.

The original implementation (7a099ebb) correctly suppressed the
`notify_category_change` job (PostAlerter path) but missed the second
notification path: `PostActionNotifier.after_create_post_revision`,
which fires via the PostRevision `after_create` callback when
`create_revision_on_bulk_topic_moves` is enabled.

This fix adds a transient `silent` attr_accessor to PostRevision, set by
PostRevisor before saving, and checked as an early return guard in
`PostActionNotifier.after_create_post_revision`.

The specs are also updated to properly enable PostActionNotifier (which
is disabled by default in tests) so the revision notification path is
actually exercised.

Ref - t/174237
2026-02-23 16:05:49 +01:00

81 lines
2.3 KiB
Ruby

# frozen_string_literal: true
class PostRevision < ActiveRecord::Base
belongs_to :post
belongs_to :user
attr_accessor :silent
serialize :modifications, type: Hash, coder: YAML
after_create :create_notification
def self.ensure_consistency!
# 1 - fix the numbers
DB.exec <<-SQL
UPDATE post_revisions
SET number = pr.rank
FROM (SELECT id, 1 + ROW_NUMBER() OVER (PARTITION BY post_id ORDER BY number, created_at, updated_at) AS rank FROM post_revisions) AS pr
WHERE post_revisions.id = pr.id
AND post_revisions.number <> pr.rank
SQL
# 2 - fix the versions on the posts
DB.exec <<-SQL
UPDATE posts
SET version = 1 + (SELECT COUNT(*) FROM post_revisions WHERE post_id = posts.id),
public_version = 1 + (SELECT COUNT(*) FROM post_revisions pr WHERE post_id = posts.id AND pr.hidden = 'f')
WHERE version <> 1 + (SELECT COUNT(*) FROM post_revisions WHERE post_id = posts.id)
OR public_version <> 1 + (SELECT COUNT(*) FROM post_revisions pr WHERE post_id = posts.id AND pr.hidden = 'f')
SQL
end
def categories
return [] if modifications["category_id"].blank?
@categories ||= Category.with_parents(modifications["category_id"])
end
def hide!
update_column(:hidden, true)
end
def show!
update_column(:hidden, false)
end
def create_notification
PostActionNotifier.after_create_post_revision(self)
end
def self.copy(original_post, target_post)
cols_to_copy = (column_names - %w[id post_id]).join(", ")
DB.exec <<~SQL
INSERT INTO post_revisions(post_id, #{cols_to_copy})
SELECT #{target_post.id}, #{cols_to_copy}
FROM post_revisions
WHERE post_id = #{original_post.id}
SQL
end
end
# == Schema Information
#
# Table name: post_revisions
#
# id :integer not null, primary key
# hidden :boolean default(FALSE), not null
# modifications :text
# number :integer
# created_at :datetime not null
# updated_at :datetime not null
# post_id :integer
# user_id :integer
#
# Indexes
#
# index_post_revisions_on_post_id (post_id)
# index_post_revisions_on_post_id_and_number (post_id,number)
# index_post_revisions_on_user_id (user_id)
#