مرشحات الموضوع المخصصة: معلمات URL لا تصل إلى `TopicQuery.options`

بينما أقوم ببناء إضافة مع فلاتر قائمة مواضيع مخصصة (مثل السعر، الموقع) باستخدام معلمات استعلام URL. يتم تحديث URL بشكل صحيح (على سبيل المثال، ...?market_item_statuses=Available)، ولكن المعلمات لا تظهر في topic_query.options على الخادم.

الإعداد:

  1. تسجيل المعامل من الجانب العميل (tecenc-discovery-params.js):

    // tecenc-discovery-params.js
    استيراد { apiInitializer } من "discourse/lib/api";
    
    تصدير افتراضي apiInitializer("1.37.3", (api) => {
      const MARKET_PARAMS_KEYS = [
        "market_price_min", "market_price_max", "market_location",
        "market_conditions", "market_warranty", "market_item_statuses"
      ];
      MARKET_PARAMS_KEYS.forEach(paramKey => {
        api.addDiscoveryQueryParam(paramKey, { replace: true, refreshModel: true });
      });
    });
    
  2. محاولة قائمة السماح على الجانب الخادم (plugin.rb):

    # plugin.rb
    وحدة ::Tecenc
      MARKET_PARAMS_KEYS = [
        :market_price_min, :market_price_max, :market_location,
        :market_conditions, :market_warranty, :market_item_statuses
      ].freeze
    end
    
    # بعد التهيئة
      إذا تم تفعيل SiteSetting.tecenc_enabled?
        إذا تم تعريف (::TopicQuery.add_custom_param_handler)
          ::Tecenc::MARKET_PARAMS_KEYS.each do |param_key|
            ::TopicQuery.add_custom_param_handler(param_key) { |value| value } # مبسط للاختصار
          end
          Rails.logger.info "[Tecenc] تم التسجيل باستخدام add_custom_param_handler."
        elsif تم تعريف (::TopicQuery) && ::TopicQuery.methods.include?(:extra_options_whitelist)
          current_whitelist = ::TopicQuery.extra_options_whitelist || []
          new_whitelist = (current_whitelist + ::Tecenc::MARKET_PARAMS_KEYS).uniq
          ::TopicQuery.extra_options_whitelist(*new_whitelist)
          Rails.logger.info "[Tecenc] تم توسيع extra_options_whitelist."
        else
          Rails.logger.warn "[Tecenc] تحذير_الإضافة: لم يتم العثور على طريقة لتسمية المعلمات لـ TopicQuery."
        end
    
  3. منطق التصفية على الجانب الخادم (plugin.rb):

    # plugin.rb (داخل بعد التهيئة / إذا تم التفعيل)
    ::TopicQuery.add_custom_filter(:"tecenc_filters") do |topics, topic_query|
      opts = topic_query.options
      Rails.logger.info "[Tecenc_TopicQuery] الخيارات: #{opts.inspect}" # سجل مهم
    
      # market_params_present = ::Tecenc::MARKET_PARAMS_KEYS.any? { |p| opts[p].present? }
      # if market_params_present
      #   # ... منطق التصفية باستخدام opts[key] ...
      # end
      topics # أو المواضيع المعدلة
    end
    

المشكلة (السجلات):

  1. فشل السماح بالمعلمات:

    [Tecenc] تحذير_الإضافة: لم يتم العثور على طريقة مناسبة (add_custom_param_handler أو extra_options_whitelist) للسماح بمعلمات مخصصة لـ TopicQuery.
    
  2. opts في TopicQuery.add_custom_filter يفتقد معلماتنا المخصصة:
    عندما يكون عنوان URL ...?market_item_statuses=Available، يُظهر السجل:

    [Tecenc_TopicQuery] الخيارات: {:category=>5, :filter=>"default", :topic_ids=>nil, :category_id=>5}
    

    لا تتواجد حالات market_item_statuses الخاصة بنا (وغيرها من المعلمات المخصصة).

بيئتنا:

أسئلة:

  1. ما هي الممارسة الأفضل الحالية لضمان وصول معاملات عنوان URL المخصصة إلى topic_query.options في إصدارات Discourse الحديثة؟
  2. لماذا قد تفشل محاولاتنا لاستخدام add_custom_param_handler أو extra_options_whitelist مع التحذير “تعذر العثور على طريقة مناسبة”؟
  3. هل هناك طريقة بديلة لتسجيل المعلمات مع TopicQuery يجب أن نستخدمها؟

أي مساعدة ستكون محل تقدير كبير!

لقد لاحظت للتو أن add_custom_param_handler غير متوفر أصلاً كطريقة على TopicQuery. هل هناك طريقة أخرى لبناء مرشحات مخصصة للمواضيع في إصدارات النقاش الأحدث؟

طرق singleton لـ TopicQuery: [:add_custom_filter, :apply_custom_filters, :new_filter, :public_valid_options, :remove_custom_filter, :remove_muted_tags, :results_filter_callbacks, :results_filter_callbacks=, :tracked_filter, :unread_filter, :valid_options, :validate?, :validators, :yaml_tag]

تقرير التقدم حتى الآن:

  1. تأكدت من أن طرق الت whitelist الثابتة لـ TopicQuery مثل add_custom_param_handler أو extra_options_whitelist غير متاحة كطرق صف في إصدار Discourse الخاص بي، لذا تم التخلي عن تلك الأساليب.

  2. نفذت تصحيحًا لـ ListController#build_topic_list_options لحقن معاييري عنوان URL المخصصة (مثل market_item_statuses، market_price_min) في قاموس opts قبل استدعاء TopicQuery.new.

  3. هذه الآن تعمل! عندما أقوم بطلب مثل /c/market/5/l/latest.json?filter=defaultmarket_item_statuses=Available، تؤكد سجلات الخادم الخاص بي الإدراج:

    [TecencMarket_ListControllerExt_BuildOptsV3] تم الحقن في opts: market_item_statuses = Available
    
    

    إذن، الآن TopicQuery.new(user, opts) يتلقى opts التي تحتوي على معاييري المخصصة.

نقطة التوقف الحالية: خطأ 500  عدم الوصول إلى كتلة الفلتر

على الرغم من أن المعايير أصبحت تمر بشكل صحيح إلى مُهيئ TopicQuery، إلا أنني لا أزال أحصل على خطأ 500 Internal Server Error عندما يتضمن الطلب تلك المعايير السوقية المخصصة.

لعزل هذه المشكلة، قمت بتبسيط كتلة TopicQuery.add_custom_filter ("tecenc_market_filters") إلى الحد الأدنى المطلق.

# plugin.rb - كتلة الفلتر المخصصة المبسطة الحالية
if ::TopicQuery.respond_to?(:add_custom_filter)
  ::TopicQuery.add_custom_filter(:"tecenc_market_filters") do |topics, topic_query|
    original_topics_relation = topics 
    opts = topic_query.options
    log_prefix_query = "[TecencMarket_SimplifiedFilter_V1.1_Test]" # بادئة تصحيح الأخطاء الخاصة بي

    Rails.logger.info "#{log_prefix_query} المعايير التي استُلمت بواسطة TopicQuery: #{opts.inspect}"

    if opts[:market_item_statuses].present?
      Rails.logger.info "#{log_prefix_query} 'market_item_statuses' موجودة في opts: #{opts[:market_item_statuses]}"
    else
      Rails.logger.info "#{log_prefix_query} 'market_item_statuses' غير موجودة في opts."
    end
    
    Rails.logger.info "#{log_prefix_query} إعادة العلاقة الأصلية للمواضيع."
    original_topics_relation # إرجاع ضمني
  end
  Rails.logger.info "[TecencMarket] تم تطبيق الفلتر المخصص المبسط (V1.1_Test)."
end

ملاحظات مع هذا الفلتر المبسط:

  • طلبات بدون معلمة الفلتر المخصصة الخاصة بي (مثل /c/market/5/l/latest.json?filter=default):

    • يتسجل الكود المخصص بشكل صحيح:

      [TecencMarket_SimplifiedFilter_V1.1_Test] المعايير التي استُلمت بواسطة TopicQuery: {:category=>5, :filter=>"default", ...}
      [TecencMarket_SimplifiedFilter_V1.1_Test] 'market_item_statuses' غير موجود في opts.
      [TecencMarket_SimplifiedFilter_V1.1_Test] إعادة العلاقة الأصلية للمواضيع.
      
      
    • الصفحة تُحمّل في حالة استلام استجابة 200 OK.

  • طلبات مع معلمة الفلتر المخصصة الخاصة بي (مثل /c/market/5/l/latest.json?filter=defaultmarket_item_statuses=Available):

    • يظهر سجل التصحيح لـ ListController: [TecencMarket_ListControllerExt_BuildOptsV3] تم الحقن في opts: market_item_statuses = Available

    • يحدث خطأ Completed 500 Internal Server Error in ...ms على الفور بعد ذلك.

    • الأهم من ذلك، لا تظهر أي سجلات من داخل كتلة الفلتر المبسط (لا خطوط [TecencMarket_SimplifiedFilter_V1.1_Test]...) لهذا الطلب الفاشل.

يشير هذا إلى أن الخطأ 500 يحدث *بعد أن يتم تهيئة TopicQuery باستخدام مجلد opts (الذي يحتوي الآن على معاييري المخصصة)، ولكن قبل أو عند محاولة آلية TopicQuery#apply_custom_filters الأساسية لـ Discourse تنفيذ كتلة الفلتر المسجلة (والمبسطة الآن).

أواجه صعوبة في عزل الاستثناء الخاص بـ Ruby الكامل والتتبع الخلفي من development.log والذي يسبق مباشرة خط “Completed 500…” للطلبات الفاشلة (القطعة من السجل التي جمعتها تظهر خط 500 نفسه، ولكن لا تفاصيل رسالة الخطأ قبل ذلك مباشرة).

سؤال متابعة:

نظراً لـ:

  1. أن المعايير المخصصة يتم حقنها بنجاح الآن في TopicQuery.options بواسطة التصحيح في ListController.

  2. حدوث خطأ 500 عندما تكون هذه المعايير المخصصة موجودة في opts.

  3. أن هذا الخطأ 500 يحدث قبل أن ينفذ كتلة الفلتر المخصصة المبسطة جدًا (التي تسجل وترجع العلاقة الأصلية فقط) أول سطر من كودها للطلب الذي يحتوي على المعايير المخصصة.

  4. أن هذا على Discourse 3.5.0.beta3-dev.

ما الذي قد يتسبب في أن TopicQuery نفسه، أو دالة apply_custom_filters، تتوقف عن العمل قبل استدعاء كتلة الفلتر المخصصة المسجلة، تحديدًا عندما تحتوي مجموعة options على مفاتيح خاصة بالإضافات؟ هل يمكن أن الـ LocalJumpError التي اشتبهنا بها لا تزال ذات صلة على مستوى أدنى في كيفية تعامل apply_custom_filters مع التكرار أو استدعاء كتل الفلتر، حتى لو كانت كتلتي المبسطة ببساطة عودة ضمنية؟

أي توجيه حول ما يجب التحقق منه بعد ذلك في سلوك TopicQuery مع هذه الأنواع من الخيارات المخصصة، أو نصائح حول كيفية الحصول بشكل موثوق على كامل تتبع الأخطاء لـ 500 في هذا السيناريو، ستكون مفيدة جدًا.