Erro 'FAILED' ao tentar desmarcar a insígnia 'Bug Reporter'

Este bug existe há muito tempo. Pesquisei sobre ele no ano passado e aqui estão os passos para reproduzi-lo:

  1. Como administrador, defina max favorite badges para 2 e crie pelo menos um distintivo que possa ser ganho várias vezes.
  2. Como usuário comum, defina dois distintivos como favoritos, sendo um deles o distintivo que pode ser ganho várias vezes (referido como Distintivo A).
  3. Como administrador, conceda novamente o Distintivo A ao usuário.
  4. Como usuário comum, atualize a página e tente desmarcar o Distintivo A como favorito. Você encontrará o erro.

A razão para o erro é que cada vez que um distintivo que pode ser ganho várias vezes é concedido, um novo registro user_badge é criado no banco de dados. No entanto, quando o usuário favoritou o distintivo e o recebe novamente, o novo registro user_badge não é automaticamente marcado como is_favorite. Quando o usuário tenta desmarcar o Distintivo A como favorito, o frontend envia o ID user_badge mais recente por padrão. Como esse registro não está marcado como is_favorite, o backend assume que o usuário está tentando definir um novo distintivo como favorito (em vez de desfavoritá-lo), o que excede o limite de max favorite badges, resultando no erro.

O código relevante está localizado em:

Uma possível solução é modificar a linha 131 para:

if UserBadge.where(badge: user_badge.badge, user: user_badge.user).pluck(:is_favorite).any? &&

No entanto, isso não aborda totalmente a inconsistência nos registros do banco de dados.

Como uma solução temporária, um usuário comum pode desfavoritar todos os distintivos executando o seguinte código JavaScript no console:

const user_name = require("discourse/models/user").default.current().username;
const badges = await require("discourse/models/user-badge").default.findByUsername(user_name);
const favorites = new Map();
badges.filter((b)=>b.is_favorite).forEach((b)=>favorites.set(b.badge_id,b));
favorites.forEach((b)=>b.favorite());
9 curtidas