커스텀 토픽 목록 필터(예: 가격, 위치)를 URL 쿼리 매개변수를 사용하여 플러그인을 개발하고 있습니다. URL은 올바르게 업데이트되지만(예: ...?market_item_statuses=Available), 서버에서 topic_query.options에 해당 매개변수가 나타나지 않습니다.
설정:
-
클라이언트 측 매개변수 등록 (tecenc-discovery-params.js):
// tecenc-discovery-params.js
import { apiInitializer } from "discourse/lib/api";
export default 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
module ::Tecenc
MARKET_PARAMS_KEYS = [
:market_price_min, :market_price_max, :market_location,
:market_conditions, :market_warranty, :market_item_statuses
].freeze
end
# after_initialize do
if SiteSetting.tecenc_enabled?
if defined?(::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] Registered with add_custom_param_handler."
elsif defined?(::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] Extended extra_options_whitelist."
else
Rails.logger.warn "[Tecenc] PLUGIN_WARN: Could not find method to whitelist params for TopicQuery."
end
-
서버 측 필터링 로직 (plugin.rb):
# plugin.rb (inside after_initialize / if enabled)
::TopicQuery.add_custom_filter(:"tecenc_filters") do |topics, topic_query|
opts = topic_query.options
Rails.logger.info "[Tecenc_TopicQuery] Opts: #{opts.inspect}" # 중요 로그
# market_params_present = ::Tecenc::MARKET_PARAMS_KEYS.any? { |p| opts[p].present? }
# if market_params_present
# # ... filtering logic using opts[key] ...
# end
topics # or modified_topics
end
문제 (로그):
-
매개변수 화이트리스트 등록 실패:
[Tecenc] PLUGIN_WARN: Could not find a suitable method (add_custom_param_handler or extra_options_whitelist) to whitelist custom params for TopicQuery.
-
TopicQuery.add_custom_filter의 opts에 사용자 정의 매개변수 누락:
URL이 ...?market_item_statuses=Available인 경우, 로그는 다음과 같이 표시됩니다:
[Tecenc_TopicQuery] Opts: {:category=>5, :filter=>"default", :topic_ids=>nil, :category_id=>5}
우리의 market_item_statuses(그리고 기타 사용자 정의 매개변수)가 존재하지 않습니다.
우리의 환경:
질문:
- 최근 Discourse 버전에서 사용자 정의 URL 쿼리 매개변수가
topic_query.options에 도달하도록 보장하는 현재 모범 사례는 무엇인가요?
add_custom_param_handler 또는 extra_options_whitelist를 사용하려는 시도가 “Could not find a suitable method” 경고와 함께 실패하는 이유는 무엇일까요?
TopicQuery의 매개변수 등록에 사용해야 할 대안적인 접근 방식이 있나요?
도움을 주시면 감사하겠습니다!
방금 add_custom_param_handler가 TopicQuery의 메서드로조차 사용 가능하지 않다는 걸 알아차렸습니다. 더 새로운 discourse 버전에서 토픽에 대한 커스텀 필터를 생성하는 다른 방법이 있을까요?
TopicQuery singleton_methods: [: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]
지금까지 진행 상황 보고서:
-
add_custom_param_handler 또는 extra_options_whitelist과 같은 정적 TopicQuery 화이트리스트 메서드가 내 Discourse 버전에서 클래스 메서드로 사용 가능하지 않음을 확인했으므로, 해당 접근 방식은 폐기되었습니다.
-
TopicQuery.new가 호출되기 전에 opts 해시에 사용자 정의 URL 파라미터(예: market_item_statuses, market_price_min)를 주입하기 위해 ListController#build_topic_list_options에 패치를 구현했습니다.
-
이 부분은 이제 작동합니다! /c/market/5/l/latest.json?filter=default&market_item_statuses=Available와 같은 요청을 수행하면 서버 로그에서 주입이 확인됩니다:
[TecencMarket_ListControllerExt_BuildOptsV3] Injected into 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} Opts received by TopicQuery: #{opts.inspect}"
if opts[:market_item_statuses].present?
Rails.logger.info "#{log_prefix_query} 'market_item_statuses' IS PRESENT in opts: #{opts[:market_item_statuses]}"
else
Rails.logger.info "#{log_prefix_query} 'market_item_statuses' IS NOT PRESENT in opts."
end
Rails.logger.info "#{log_prefix_query} Returning original topics relation."
original_topics_relation # 암시적 반환
end
Rails.logger.info "[TecencMarket] Applied SIMPLIFIED custom filter (V1.1_Test)."
end
이 단순화된 필터에 대한 관찰 사항:
이는 500 에러가 TopicQuery가 이제 사용자 정의 파라미터를 포함한 opts 해시로 초기화된 이후에, 그러나 Discourse 코어 TopicQuery#apply_custom_filters 메커니즘이 등록된(이제 매우 단순해진) 필터 블록을 실행하려는 직전 또는 그 시점에 발생한다는 것을 의미합니다.
실패하는 요청의 “Completed 500…” 라인 바로 직전에 있는 development.log의 특정 Ruby 예외와 전체 백트레이스를 분리하는 데 어려움을 겪고 있습니다(수집한 로그 스니펫은 500 라인 자체는 보여주지만, 그 직전의 상세한 에러 메시지는 보여주지 않습니다).
추가 질문:
다음 사항이 주어졌을 때:
-
사용자 정의 파라미터가 이제 ListController 패치를 통해 TopicQuery.options에 성공적으로 주입되고 있습니다.
-
이러한 사용자 정의 파라미터가 opts에 존재할 때 500 에러가 발생합니다.
-
이 500 에러는 사용자 정의 파라미터가 포함된 요청에 대해, 단순히 로깅하고 원래 관계를 반환하는 극도로 단순화된 사용자 정의 필터 블록조차 그 첫 번째 코드 라인을 실행하기 전에 발생합니다.
-
이는 Discourse 3.5.0.beta3-dev 환경입니다.
options 해시에 이러한 플러그인 전용 키가 포함되었을 때, 등록된 사용자 정의 필터 블록을 호출하기 전에 TopicQuery 자체나 그 apply_custom_filters 메서드가 에러를 일으키는 원인은 무엇일 수 있을까요? 제 단순화된 블록이 암시적 반환일 뿐이더라도, apply_custom_filters가 필터 블록의 반복이나 호출을 처리하는 하위 레벨에서 이전에 의심했던 LocalJumpError가 여전히 관련이 있을 수 있을까요?
이러한 유형의 사용자 정의 옵션에 대한 TopicQuery의 동작에 대해 다음으로 무엇을 확인해야 하는지, 또는 이 시나리오에서 500 에러의 전체 백트레이스를 견고하게 얻는 방법에 대한 조언은 큰 도움이 될 것입니다.