discourse/app/jobs/regular/bulk_user_title_update.rb
Martin Brennan 56d3e29a69
FIX: Badge and user title interaction fixes (#8282)
* Fix user title logic when badge name customized
* Fix an issue where a user's title was not considered a badge granted title when the user used a badge for their title and the badge name was customized. this affected the effectiveness of revoke_ungranted_titles! which only operates on badge_granted_titles.
* When a user's title is set now it is considered a badge_granted_title if the badge name OR the badge custom name from TranslationOverride is the same as the title
* When a user's badge is revoked we now also revoke their title if the user's title matches the badge name OR the badge custom name from TranslationOverride
* Add a user history log when the title is revoked to remove confusion about why titles are revoked
* Add granted_title_badge_id to user_profile, now when we set badge_granted_title on a user profile when updating a user's title based on a badge, we also remember which badge matched the title
* When badge name (or custom text) changes update titles of users in a background job
* When the name of a badge changes, or in the case of system badges when their custom translation text changes, then we need to update the title of all corresponding users who have a badge_granted_title and matching granted_title_badge_id. In the case of system badges we need to first get the proper badge ID based on the translation key e.g. badges.regular.name
* Add migration to backfill all granted_title_badge_ids for both normal badge name titles and titles using custom badge text.
2019-11-08 15:34:24 +10:00

52 lines
1.7 KiB
Ruby

# frozen_string_literal: true
module Jobs
class BulkUserTitleUpdate < ::Jobs::Base
UPDATE_ACTION = 'update'.freeze
RESET_ACTION = 'reset'.freeze
def execute(args)
new_title = args[:new_title]
granted_badge_id = args[:granted_badge_id]
action = args[:action]
case action
when UPDATE_ACTION
update_titles_for_granted_badge(new_title, granted_badge_id)
when RESET_ACTION
reset_titles_for_granted_badge(granted_badge_id)
end
end
private
##
# If a badge name or a system badge TranslationOverride changes
# then we need to set all titles granted based on that badge to
# the new name or custom translation
def update_titles_for_granted_badge(new_title, granted_badge_id)
DB.exec(<<~SQL, granted_title_badge_id: granted_badge_id, title: new_title, updated_at: Time.now)
UPDATE users AS u
SET title = :title, updated_at = :updated_at
FROM user_profiles AS up
WHERE up.user_id = u.id AND up.granted_title_badge_id = :granted_title_badge_id
SQL
end
##
# Reset granted titles for a badge back to the original
# badge name. When a system badge has its TranslationOverride
# revoked we want to have all titles based on that translation
# for the badge reset.
def reset_titles_for_granted_badge(granted_badge_id)
DB.exec(<<~SQL, granted_title_badge_id: granted_badge_id, updated_at: Time.now)
UPDATE users AS u
SET title = badges.name, updated_at = :updated_at
FROM user_profiles AS up
INNER JOIN badges ON badges.id = up.granted_title_badge_id
WHERE up.user_id = u.id AND up.granted_title_badge_id = :granted_title_badge_id
SQL
end
end
end