Este error ha existido durante mucho tiempo. Lo investigué el año pasado y estos son los pasos para reproducirlo:
- Como administrador, establece
max favorite badgesen 2 y crea al menos una insignia que se pueda ganar varias veces. - Como usuario normal, marca dos insignias como favoritas, una de las cuales es la insignia que se puede ganar varias veces (denominada Insignia A).
- Como administrador, otorga nuevamente la Insignia A al usuario.
- Como usuario normal, actualiza la página e intenta quitar la Insignia A de los favoritos. Te encontrarás con el error.
La razón del error es que cada vez que se otorga una insignia que se puede ganar varias veces, se crea un nuevo registro user_badge en la base de datos. Sin embargo, cuando el usuario ha marcado la insignia como favorita y luego la recibe nuevamente, el nuevo registro user_badge no se marca automáticamente como is_favorite. Cuando el usuario intenta quitar la Insignia A de los favoritos, el frontend envía por defecto el ID de user_badge más reciente. Dado que este registro no está marcado como is_favorite, el backend asume que el usuario está intentando marcar una nueva insignia como favorita (en lugar de quitarla de los favoritos), lo que excede el límite de max favorite badges, lo que resulta en el error.
El código relevante se encuentra en:
Una posible solución es modificar la línea 131 a:
if UserBadge.where(badge: user_badge.badge, user: user_badge.user).pluck(:is_favorite).any? &&
Sin embargo, esto no aborda completamente la inconsistencia en los registros de la base de datos.
Como solución temporal, un usuario normal puede quitar todas las insignias de los favoritos ejecutando el siguiente código JavaScript en la consola:
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());