저는 플러그인을 만들기로 결정했습니다. 폼 컴포넌트 자체는 api.renderInOutlet을 통해 올바르게 렌더링됩니다. 그러나 데이터가 백엔드의 커스텀 테이블에 저장되지 않습니다.
프론트엔드 설정:
지정된 카테고리에서 새 토픽이 생성될 때 GJS 컴포넌트(MyOutletConnectorComponent)를 렌더링하기 위해 api.renderInOutlet("composer-fields", MyOutletConnectorComponent)를 사용하고 있습니다.
이 MyOutletConnectorComponent는 제 메인 GJS 폼 컴포넌트(MyMarketFormComponenent)를 렌더링합니다.
MyMarketFormComponenent 내부에서, 사용자 입력은 자바스크립트 객체를 업데이트하고, 이 객체는 아웃렛 인수로 제공되는 composerModel의 최상위 속성으로 설정됩니다. 예를 들어:
// MyMarketFormComponenent 액션 내부
const currentData = this.args.composerModel.get("market_listing_data") || {};
const updatedData = { ...currentData, [fieldKey]: newValue };
this.args.composerModel.set("market_listing_data", updatedData);
플러그인 초기화 파일(tecenc-market-composer.js)에서, 이 데이터를 백엔드로 전달하기 위해 api.serializeOnCreate("market_listing_data", "market_listing_data");를 사용하고 있습니다. 또한 api.serializeToDraft("market_listing_data", "market_listing_data");도 사용하고 있습니다.
백엔드 문제:
plugin.rb에서 DiscourseEvent.on(:topic_created) do |topic, opts, user| ... end 핸들러 내부에서:
토픽이 올바른 카테고리에 있는지 확인합니다(이 부분은 작동합니다).
그런 다음 market_data = opts[:market_listing_data](또는 opts["market_listing_data"])를 사용하여 직렬화된 데이터에 접근하려고 합니다.
문제는 opts[:market_listing_data]가 일관되게 nil이라는 점입니다.
opts.keys를 로그로 출력하면 market_listing_data 키가 opts 해시의 최상위에 존재하지 않는 것이 확인됩니다. opts 해시 자체에는 :raw, :title, :category, :archetype과 같은 표준 키가 포함되어 있습니다.
이벤트를 위한 제 plugin.rb 스니펫:
# plugin.rb
# ...
module ::TecencMarket
SERIALIZED_DATA_KEY = "market_listing_data".freeze
end
# ...
after_initialize do
# ...
DiscourseEvent.on(:topic_created) do |topic, opts, user|
# ... (카테고리 확인 로직) ...
# 여기서 market_data가 nil인 곳
market_data = opts[TecencMarket::SERIALIZED_DATA_KEY.to_sym]
Rails.logger.info "[MyPlugin] Opts keys: #{opts.keys.inspect}"
Rails.logger.info "[MyPlugin] market_data from opts: #{market_data.inspect}"
if market_data.present? && market_data.is_a?(Hash)
# ... 데이터를 처리하고 커스텀 테이블에 저장 ...
else
Rails.logger.warn "[MyPlugin] Market data not found in opts as expected."
end
end
# ...
end
질문:
GJS 컴포넌트를 사용하여 composerModel의 최상위 속성으로 설정된 자바스크립트 객체(예: composerModel.set("my_plugin_data_key", { ... });)가 api.serializeOnCreate에 의해 올바르게 직렬화되어 백엔드의 :topic_created 이벤트에서 opts 해시로 사용 가능하도록 하는 가장 정확하고 신뢰할 수 있는 방법은 무엇인가요?
api.serializeOnCreate("my_key", "my_key")는 GJS 컨텍스트에서 composerModel에 설정된 임의의 최상위 키에 대해 작동하도록 기대할 수 있나요, 아니면 custom_fields를 통한 직렬화(예: composerModel.custom_fields.my_plugin_key = {...} 설정 및 api.serializeOnCreate("custom_fields.my_plugin_key") 사용)가 새 토픽에 대한 이 유형의 데이터 전송에 대해 유일하게 견고하고 권장되는 접근 방식인가요?
api.serializeOnCreate를 GJS 컴포넌트에 의해 관리되는 데이터와 함께 사용할 때, 데이터가 opts 해시에 포함되지 않도록 만드는 특정 고려 사항이나 일반적인 함정이 있나요?
프론트엔드 폼이 데이터를 올바르게 수집하고 composerModel.market_listing_data 속성에 설정하고 있음을 확인했습니다. 문제는 이 데이터를 직렬화하여 백엔드 이벤트로 전달하는 부분에 있는 것 같습니다.
최신 Discourse에서 이를 위한 권장 패턴에 대한 지침이나 예시가 있다면 매우 감사하겠습니다!
opts 해시로 데이터가 전달되지 않는다는 이전 문제를 이어서 말씀드리고자 합니다. 이제 플러그인의 컴포저 폼에서 데이터를 직렬화하는 데 권장되는 custom_fields 경로를 사용하도록 전략을 변경했습니다.
현재 접근 방식:
프론트엔드 초기화기:
composerModel.custom_fields와 composerModel.custom_fields["tecenc_market_data"](제 플러그인의 데이터 키)가 객체로 초기화되도록 보장하려고 시도하고 있습니다. 최근 시도는 api.modifyClass("model:composer", ...)를 사용하여 init()과 clearState()에 초기화 로직을 추가하는 것입니다:
:topic_created 이벤트 핸들러는 topic.custom_fields["tecenc_market_data"]에서 데이터를 읽을 것을 기대합니다.
새로운 차단 오류:
composerModel에서 custom_fields를 초기화하기 위한 이러한 시도에도 불구하고, 새 주제를 위한 컴포저를 열려고 할 때(“주제 만들기” 버튼을 클릭하여) 일관되게 다음과 같은 JavaScript 오류를 겪고 있습니다:
Uncaught (in promise) Error: Property set failed: object in path "custom_fields" could not be found.
Ember 3
open composer.js:1010
open composer.js:1009
_setModel composer.js:1451
open composer.js:1401
openNewTopic composer.js:1410
createTopic list.js:167
clickCreateTopicButton d-navigation.gjs:224
_triggerAction d-button.gjs:138
Ember 11
_triggerAction d-button.gjs:135
click d-button.gjs:93
source chunk.8d6366d70b85d1b69fdc.d41d8cd9.js:94366
Ember 2
source chunk.8d6366d70b85d1b69fdc.d41d8cd9.js:94040
Ember 26 property_set-BapAkp3X.js:79:10
이 오류는 composer.js:1010의 코어 Discourse 코드(openNewTopic에 의해 호출되는 open 메서드 내부)가 중첩된 프로퍼티를 설정하려고 할 때 composerModel의 this.model.custom_fields가 undefined 또는 null임을 나타냅니다. 이는 제 플러그인의 폼이 렌더링되기 이전에 발생합니다.
질문:
코어 Composer 모델이 custom_fields: {}를 초기화해야 하는데, 왜 이 Discourse 버전에서 openNewTopic 시퀀스 중 composer.js:1010에서 composerModel.custom_fields가 여전히 undefined일 수 있을까요?
초기화기에서 api.modifyClass("model:composer", ...) 접근 방식이 이 코어 오류를 방지하기 위해 충분히 일찍 custom_fields(그 안의 중첩된 플러그인 키 포함)가 객체로 초기화되도록 보장하는 가장 효과적이고 올바른 방법인가요? 그렇지 않다면, 권장되는 패턴은 무엇인가요?
api.modifyClass를 사용하는 플러그인 초기화기가 Composer 모델 프로토타입이나 인스턴스에 완전히 효과를 발휘하기 전에 코어 컴포저 초기화 단계가 실행되어 custom_fields를 기대하는 타이밍 문제가 있을 수 있나요?
컴포저 코어에서의 이 “Property set failed” 오류에 대한 통찰력과 초기화 동안 composerModel.custom_fields와 안전하게 상호작용하는 플러그인의 모범 사례에 대한 조언은 매우 도움이 될 것입니다.
addToSerializer는 데이터를 서버에서 클라이언트로 전송하는 데 사용되는 것 아닌가요?
제 문제는 데이터를 클라이언트에서 서버로 전송하여 저장하는 것입니다. 그래서 serializeOnCreate를 사용하고 있습니다. 하지만 문제는 데이터가 opts 해시로 흘러들어가지 않는다는 점입니다. 즉, 현재로서는 아니요, 사용자 정의 데이터가 예상대로 opts 해시로 들어가지 않습니다. Rails로 전달되지도 않습니다.
이 교육용 플러그인을 살펴봤지만, 6개의 사용자 정의 필드에 적용해 작동시키는 데 실패했습니다.