خطأ 'FAILED' عند محاولة إلغاء النجمة لشارة 'Bug Reporter'

هذه المشكلة موجودة منذ فترة طويلة. لقد بحثت فيها العام الماضي، وهذه هي خطوات إعادة إنتاجها:

  1. بصفتك مسؤولاً، قم بتعيين max favorite badges إلى 2، وأنشئ شارة واحدة على الأقل يمكن كسبها عدة مرات.
  2. بصفتك مستخدمًا عاديًا، قم بتعيين شارتين كمفضلتين، إحداهما هي الشارة التي يمكن كسبها عدة مرات (يشار إليها باسم الشارة أ).
  3. بصفتك مسؤولاً، امنح المستخدم الشارة أ مرة أخرى.
  4. بصفتك مستخدمًا عاديًا، قم بتحديث الصفحة وحاول إلغاء تمييز الشارة أ كمفضلة. ستواجه الخطأ.

سبب الخطأ هو أنه في كل مرة يتم فيها منح شارة يمكن كسبها عدة مرات، يتم إنشاء سجل user_badge جديد في قاعدة البيانات. ومع ذلك، عندما يفضل المستخدم الشارة ويتلقاها مرة أخرى، لا يتم تمييز سجل user_badge الجديد تلقائيًا على أنه is_favorite. عندما يحاول المستخدم إلغاء تمييز الشارة أ كمفضلة، يرسل الواجهة الأمامية معرف user_badge الأحدث افتراضيًا. نظرًا لأن هذا السجل غير مميز على أنه is_favorite، يفترض الواجهة الخلفية أن المستخدم يحاول تعيين شارة جديدة كمفضلة (بدلاً من إلغاء تمييزها كمفضلة)، مما يتجاوز حد max favorite badges، مما يؤدي إلى الخطأ.

يقع الكود ذو الصلة في:

أحد الحلول الممكنة هو تعديل السطر 131 إلى:

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

ومع ذلك، هذا لا يعالج بشكل كامل عدم الاتساق في سجلات قاعدة البيانات.

كحل مؤقت، يمكن للمستخدم العادي إلغاء تمييز جميع الشارات كمفضلة عن طريق تشغيل كود JavaScript التالي في وحدة التحكم:

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 إعجابات