discourse/lib/migration/group_mention_slug_rewriter.rb
Martin Brennan 5ff45e59b7
DEV: Rename anonymous group to anonymous_users (#40435)
Followup 9359227645

As pointed out in https://meta.discourse.org/t/-/404037,
the group name "anonymous" is too generic and can conflict
with existing _users_ as well as existing groups. This commit
renames it to "anonymous_users" to avoid such conflicts, and
also to match "logged_in_users" a bit better.

In addition, this PR fixes some issues with the upcoming
change introduced in 9359227645bb3a3cb4c17d9313d9aadfc545c563...
the anonymous/logged_in_users groups were not showing in the admin
UI when the UC was enabled, and the logic for keeping everyone
saved in the DB for now was not working for site settings.
2026-06-02 09:29:46 +10:00

47 lines
1.5 KiB
Ruby
Vendored

# frozen_string_literal: true
module Migration
# Rewrites @group mentions in post raw when a group slug is renamed during a
# migration. Boundaries match Jobs::UpdateUsername (not trailing whitespace only).
module GroupMentionSlugRewriter
NON_TRAILING_MENTION_CHAR_CLASS = "[:alnum:]_\\-.`"
module_function
def update_posts!(old_slug:, new_slug:, group_id:)
pattern = mention_pattern_sql(old_slug)
DB.exec(<<~SQL, pattern:, new_slug:, group_id:, old_slug:)
UPDATE posts AS p SET
raw = regexp_replace(
p.raw,
:pattern,
E'\\1@' || :new_slug,
'g'
),
baked_version = NULL
WHERE p.deleted_at IS NULL
AND EXISTS (
SELECT 1
FROM group_mentions gm
WHERE gm.post_id = p.id
AND gm.group_id = :group_id
)
AND p.raw LIKE '%@' || :old_slug || '%';
SQL
end
# Ruby equivalent of the SQL pattern for unit tests.
def rewrite_text(text, old_slug, new_slug)
text.gsub(mention_pattern_ruby(old_slug), "\\1@#{new_slug}")
end
def mention_pattern_sql(old_slug)
"(^|[^#{NON_TRAILING_MENTION_CHAR_CLASS}])@#{Regexp.escape(old_slug)}(?=[^#{NON_TRAILING_MENTION_CHAR_CLASS}]|$)"
end
def mention_pattern_ruby(old_slug)
/(^|[^#{NON_TRAILING_MENTION_CHAR_CLASS}])@#{Regexp.escape(old_slug)}(?=[^#{NON_TRAILING_MENTION_CHAR_CLASS}]|$)/
end
end
end