تغيير ملكية مجمّعة للمشاركات الأولى حسب الوسم - مراجعة السكريبت واقتراحات

مرحباً،

أنا أتطلع إلى تغيير ملكية جميع المشاركات الافتتاحية في مواضيع الأحداث التي تحمل وسم “ethan” بحيث يتغير المالك من “system” إلى المستخدم “Ethan_Hoom1”. أنا أدير نسخة مستضافة ذاتياً ولدي وصول إلى Rails console.

بعد مراجعة التوصيات في العمليات الإدارية المجمعة و تغيير ملكية جميع المشاركات لمستخدم معين، أعددت البرنامج النصي التالي. سأكون ممتناً لأي اقتراحات أو أفضل الممارسات قبل تشغيله في بيئة الإنتاج:


# ابحث عن كائن الوسم بالاسم "ethan"
tag = Tag.find_by(name: "ethan")

# توقف فوراً إذا لم يتم العثور على الوسم
raise "Tag not found" unless tag


# ابحث عن المستخدم الذي سيصبح المالك الجديد للمشاركات
# username_lower أكثر أماناً من username (غير حساس لحالة الأحرف)
new_owner = User.find_by(username_lower: "ethan_hoom1")

# توقف فوراً إذا لم يتم العثور على المستخدم الهدف
raise "New owner user not found" unless new_owner


# ابحث عن حساب المستخدم system
# استخدم Discourse.system_user كخيار احتياطي في حال فشل البحث عن السجل
system_user = User.find_by(username_lower: "system") || Discourse.system_user

# توقف فوراً إذا لم يتم العثور على المستخدم system
raise "System user not found" unless system_user


# عندما تكون القيمة true، سيقوم البرنامج النصي بطباعة ما سيتم تغييره فقط
# ولن يقوم بإجراء أي تعديلات في قاعدة البيانات
DRY_RUN = true

# حد أمان اختياري للتشغيل الأول (على سبيل المثال 10 أو 50)
# اضبطها على nil لمعالجة جميع المشاركات المطابقة
LIMIT = nil


# بناء استعلام ActiveRecord للمشاركات التي نريد تعديلها
scope = Post
  # ربط المشاركات ← المواضيع ← وسم_الموضوعات حتى نتمكن من التصفية حسب الوسم
  .joins(topic: :topic_tags)

  # استهداف المشاركة الافتتاحية في كل موضوع فقط
  .where(post_number: 1)

  # استهداف المشاركات المملوكة حالياً للمستخدم system فقط
  .where(user_id: system_user.id)

  # تضمين المواضيع التي تحمل وسم "ethan" فقط
  .where(topic_tags: { tag_id: tag.id })

  # استبعاد الرسائل الخاصة والمواضيع المحذوفة
  .where(topics: {
    archetype: Archetype.default,
    deleted_at: nil
  })


# إذا تم تعيين LIMIT، قم بتقييد عدد المشاركات التي تتم معالجتها
scope = scope.limit(LIMIT) if LIMIT


# التكرار عبر المشاركات المطابقة على دفعات لتجنب مشاكل الذاكرة
scope.find_each(batch_size: 100) do |first_post|

  # تخزين معرف الموضوع للإخراج المسجل
  topic_id = first_post.topic_id


  # إذا كان وضع التشغيل الجاف ممكناً، فلا تقم بإجراء أي تعديلات
  if DRY_RUN
    puts "[DRY RUN] Would change owner for topic #{topic_id} (post #{first_post.id})"
    next
  end


  begin
    # استخدام خدمة تغيير مالك المشاركة الرسمية لـ Discourse
    PostOwnerChanger.new(
      # تغيير ملكية المشاركة الافتتاحية فقط
      post_ids: [first_post.id],

      # الموضوع الذي يحتوي على المشاركة
      topic_id: topic_id,

      # المستخدم الذي سيصبح المالك الجديد
      new_owner: new_owner,

      # المستخدم الذي يقوم بالإجراء (المستخدم system)
      acting_user: system_user,

      # لا تقم بإنشاء مراجعة تحرير لهذا التغيير
      skip_revision: true
    ).change_owner!


    # تسجيل النجاح في وحدة التحكم
    puts "Changed owner for topic #{topic_id} (post #{first_post.id})"

  rescue => e
    # إذا فشل أي شيء، سجل الخطأ ولكن استمر في معالجة العناصر الأخرى
    puts "FAILED topic #{topic_id} (post #{first_post.id}): #{e.class}: #{e.message}"
  end
end

أسئلة:

  • هل هناك أي محاذير أو حالات حافة يجب أن أكون على دراية بها بخصوص PostOwnerChanger لهذا الاستخدام؟
  • هل من المستحسن تحديث حقل topic.user أيضاً كما هو موضح في السطر الاختياري؟
  • هل لديك أي توصيات لمزيد من التحسينات المتعلقة بالسلامة أو الأداء فيما يتعلق بهذه العملية المجمعة؟

شكراً لمساعدتكم ولكل الوثائق الرائعة!

إعجاب واحد (1)