皆さん、こんにちは。
Discourse のシリアライザーの拡張方法を学んでいるのですが、まだ完全には理解できていない動作に遭遇しました。
PostSerializer#raw をオーバーライドするために、このコードを追加しました。
require_dependency "post_serializer"
class ::PostSerializer
def raw
if scope.can_edit?(object)
object.raw
else
object.raw&.truncate(300)
end
end
end
これは完璧に動作します。
しかし、これを super を使用するように変更すると、次のようになります。
require_dependency "post_serializer"
class ::PostSerializer
def raw
if scope.can_edit?(object)
super
else
object.raw&.truncate(300)
end
end
end
scope.can_edit?(object) が true の場合、super の呼び出しが /posts/<id>.json で 500 エラー を返す原因となります。
object.raw を super の代わりに使うことで問題を回避できることは分かっていますが、特に他のメソッド(cooked、post_stream など)もオーバーライドしていて、それらのケースでは super が正常に動作するため、なぜ super がこのケースで例外を引き起こすのか を理解したいのです。
Discourse の内部構造にはまだ慣れていないため、以下の点について説明していただけると大変助かります。
PostSerializer#raw 内で super が実際に解決するものは何か
なぜこのケースで super を呼び出すと 500 エラーになるのか
なぜ raw は cooked のようなメソッドとは異なる動作をするのか
よろしくお願いします!
pfaffman
(Jay Pfaffman)
2025 年 12 月 4 日午後 11:47
2
これは、通常の投稿のシリアライザに raw が含まれていないためだと確信しています。raw が含まれるのは編集時だけです。投稿を表示するには cooked が必要なだけであり、必要でないときに raw も含めるのは無駄になります。
cooked と post_stream はシリアライザに含まれているため、super は機能します。
pangbo
2025 年 12 月 5 日午後 2:41
3
これはRubyの機能です。class ::PostSerializerを使用すると、元のクラスから継承するのではなく、その定義を上書き しています。PostSerializerを継承していないため、superは対応するメソッドを見つけることができません。
すでに定義されているクラスを再オープンする代わりに、prependを使用する必要があります。
「いいね!」 4
RGJ
(Richard - Communiteq)
2025 年 12 月 5 日午後 3:18
4
説明ありがとうございます!
おっしゃる通り、::PostSerializer を再オープンしていたのが問題でした。prepend に切り替えたところ、すべて期待どおりに動作しました。
現在、このモジュールを使用しています。
module PostSerializerExtension
def raw
if scope.can_edit?(object)
super
else
object.raw&.truncate(300)
end
end
end
reloadable_patch do
require_dependency "post_serializer"
::PostSerializer.prepend(::PostSerializerExtension)
end
これは私の環境では完璧に動作します。改めてご指導ありがとうございました!
pfaffman
(Jay Pfaffman)
2025 年 12 月 5 日午後 7:58
7
ああ、そうか。知ってたよ。なんでそれが答えじゃなかったのかわからないな。
「いいね!」 2
RGJ
(Richard - Communiteq)
2025 年 12 月 5 日午後 8:37
8
技術的には、あなたの回答は500エラーを説明しているので正解でした。
「いいね!」 1
pfaffman
(Jay Pfaffman)
2025 年 12 月 5 日午後 8:39
9
彼が尋ねた質問には私が答えた。あなたが答えたのは彼が尋ねるべきだった質問だ!
でも、少なくとも私は正解した。
「いいね!」 1