PostSerializer#raw에서 super를 호출하면 500 오류가 발생하는데, object.raw를 호출하면 정상 작동하는 이유는?

안녕하세요,

Discourse 직렬화기(serializer)를 확장하는 방법을 배우고 있는데, 완전히 이해하지 못하는 동작에 부딪혔습니다.

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>.json500 오류를 반환합니다.

super 대신 object.raw를 사용하면 문제를 피할 수 있다는 것은 알고 있지만, 왜 이 경우 super가 예외를 발생시키는지 이해하고 싶습니다. 특히 cooked, post_stream 등 다른 메서드도 오버라이드했는데, 그 경우들은 super가 정상적으로 작동하기 때문입니다.

아직 Discourse 내부 구조에 익숙하지 않아 다음 사항에 대한 설명을 정말로 듣고 싶습니다:

  • PostSerializer#raw 내부에서 super가 실제로 무엇으로 해석되는지,
  • 이 경우 super를 호출하면 500 오류로 이어지는 이유,
  • 그리고 cooked 같은 메서드와 비교했을 때 raw가 다르게 동작하는 이유.

도움 주시면 감사하겠습니다!

정상적인 게시물의 직렬화기(serializer)에는 raw가 포함되어 있지 않기 때문이라고 확신합니다. raw는 게시물을 수정할 때만 포함됩니다. 게시물을 표시하려면 cooked만 있으면 충분하므로, 필요하지 않을 때 raw까지 포함하는 것은 낭비이기 때문입니다.

cookedpost_stream은 직렬화기에 포함되어 있으므로 super가 정상적으로 작동합니다.

이것은 Ruby의 특징입니다. class ::PostSerializer를 사용하면 기존 클래스의 정의를 상속하는 대신 오버라이드하게 됩니다. PostSerializer를 상속하지 않기 때문에 super가 해당 메서드를 찾을 수 없습니다.

이미 정의된 클래스를 다시 열기보다는 prepend를 사용해야 합니다.

add_to_serializer를 사용해야 합니다.

예: How to add user data to the post serializer?

설명 감사합니다!
말씀하신 대로 ::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

제 환경에서는 완벽하게 작동합니다. 도움 주셔서 다시 한번 감사합니다!

아니 :roll_eyes: 그건 방법이 아니에요

아, 그래. 그건 알았지. 왜 그걸 답으로 안 냈는지 모르겠네. :person_shrugging:

기술적으로 당신의 답변이 정답이었으며, 500 오류를 설명하기 때문입니다.

나는 그가 한 질문에 답했습니다. 당신은 그가 해야 할 질문에 답했네요!

하지만 적어도 나는 제대로 답했습니다.