بينما أقوم ببناء إضافة مع فلاتر قائمة مواضيع مخصصة (مثل السعر، الموقع) باستخدام معلمات استعلام URL. يتم تحديث URL بشكل صحيح (على سبيل المثال، ...?market_item_statuses=Available)، ولكن المعلمات لا تظهر في topic_query.options على الخادم.
الإعداد:
-
تسجيل المعامل من الجانب العميل (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 });
});
});
-
محاولة قائمة السماح على الجانب الخادم (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
-
منطق التصفية على الجانب الخادم (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
المشكلة (السجلات):
-
فشل السماح بالمعلمات:
[Tecenc] تحذير_الإضافة: لم يتم العثور على طريقة مناسبة (add_custom_param_handler أو extra_options_whitelist) للسماح بمعلمات مخصصة لـ TopicQuery.
-
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 الخاصة بنا (وغيرها من المعلمات المخصصة).
بيئتنا:
أسئلة:
- ما هي الممارسة الأفضل الحالية لضمان وصول معاملات عنوان URL المخصصة إلى
topic_query.options في إصدارات Discourse الحديثة؟
- لماذا قد تفشل محاولاتنا لاستخدام
add_custom_param_handler أو extra_options_whitelist مع التحذير “تعذر العثور على طريقة مناسبة”؟
- هل هناك طريقة بديلة لتسجيل المعلمات مع
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]
تقرير التقدم حتى الآن:
-
تأكدت من أن طرق الت whitelist الثابتة لـ TopicQuery مثل add_custom_param_handler أو extra_options_whitelist غير متاحة كطرق صف في إصدار Discourse الخاص بي، لذا تم التخلي عن تلك الأساليب.
-
نفذت تصحيحًا لـ ListController#build_topic_list_options لحقن معاييري عنوان URL المخصصة (مثل market_item_statuses، market_price_min) في قاموس opts قبل استدعاء TopicQuery.new.
-
هذه الآن تعمل! عندما أقوم بطلب مثل /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 نفسه، ولكن لا تفاصيل رسالة الخطأ قبل ذلك مباشرة).
سؤال متابعة:
نظراً لـ:
-
أن المعايير المخصصة يتم حقنها بنجاح الآن في TopicQuery.options بواسطة التصحيح في ListController.
-
حدوث خطأ 500 عندما تكون هذه المعايير المخصصة موجودة في opts.
-
أن هذا الخطأ 500 يحدث قبل أن ينفذ كتلة الفلتر المخصصة المبسطة جدًا (التي تسجل وترجع العلاقة الأصلية فقط) أول سطر من كودها للطلب الذي يحتوي على المعايير المخصصة.
-
أن هذا على Discourse 3.5.0.beta3-dev.
ما الذي قد يتسبب في أن TopicQuery نفسه، أو دالة apply_custom_filters، تتوقف عن العمل قبل استدعاء كتلة الفلتر المخصصة المسجلة، تحديدًا عندما تحتوي مجموعة options على مفاتيح خاصة بالإضافات؟ هل يمكن أن الـ LocalJumpError التي اشتبهنا بها لا تزال ذات صلة على مستوى أدنى في كيفية تعامل apply_custom_filters مع التكرار أو استدعاء كتل الفلتر، حتى لو كانت كتلتي المبسطة ببساطة عودة ضمنية؟
أي توجيه حول ما يجب التحقق منه بعد ذلك في سلوك TopicQuery مع هذه الأنواع من الخيارات المخصصة، أو نصائح حول كيفية الحصول بشكل موثوق على كامل تتبع الأخطاء لـ 500 في هذا السيناريو، ستكون مفيدة جدًا.