# 在 PostSerializer#raw 中调用 super 导致 500 错误，而调用 object.raw 却可以工作的原因是什么？

**URL:** https://meta.discourse.org/t/why-does-calling-super-in-postserializer-raw-cause-a-500-error-while-calling-object-raw-works/390455
**Category:** Development
**Created:** [2025年十二月4日 21:24 UTC](https://meta.discourse.org/t/why-does-calling-super-in-postserializer-raw-cause-a-500-error-while-calling-object-raw-works/390455 "2025-12-04T21:24:41Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![copymonopoly](https://avatars.discourse-cdn.com/v4/letter/c/4491bb/32.png) [@copymonopoly](https://meta.discourse.org/u/copymonopoly)
#### Post date: [2025年十二月4日 21:24 UTC](https://meta.discourse.org/t/why-does-calling-super-in-postserializer-raw-cause-a-500-error-while-calling-object-raw-works/390455/1 "2025-12-04T21:24:41Z")

</div>

大家好，

我正在学习如何扩展 Discourse 的序列化器（serializer），遇到了一个我不完全理解的行为。

我添加了以下代码来覆盖 `PostSerializer#raw`：

```plaintext
require_dependency "post_serializer"

class ::PostSerializer
  def raw
    if scope.can_edit?(object)
      object.raw
    else
      object.raw&.truncate(300)
    end
  end
end

```

这运行得非常完美。

然而，如果我将其更改为使用 `super`：

```plaintext
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)` 为 **真** 时，调用 `super` 导致 `/posts/:id.json` 返回 **500 错误** 。

我知道通过使用 `object.raw` 而不是 `super` 可以避免这个问题，但我很想了解 **为什么在这种情况下调用 `super` 会导致 500 错误** ，特别是考虑到我也覆盖了其他方法（如 `cooked`、`post_stream` 等），并且在那些情况下调用 `super` 运行正常。

由于我对 Discourse 的内部机制还不太熟悉，我非常希望能得到以下方面的解释：

- `super` 在 `PostSerializer#raw` 内部实际解析为什么；
- 为什么在这种情况下调用 `super` 会导致 500 错误；
- 为什么 `raw` 的行为与 `cooked` 等方法不同。

提前感谢任何帮助！

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2025年十二月4日 23:47 UTC](https://meta.discourse.org/t/why-does-calling-super-in-postserializer-raw-cause-a-500-error-while-calling-object-raw-works/390455/2 "2025-12-04T23:47:04Z")

</div>

> [@copymonopoly](#):
>
> 我知道通过使用 `object.raw` 而不是 `super` 可以避免这个问题，但我想了解 **为什么 `super` 在这里会引发异常** ，特别是当我重写其他方法（如 `cooked`、`post_stream` 等）时，`super` 在那些情况下都能正常工作。

我非常确定这是因为 `raw` 不在普通帖子的序列化器中。只有在编辑时才会包含 `raw`。要显示帖子，只需要 `cooked`；在不需要 `raw` 的情况下也包含它是一种浪费。

`cooked` 和 `post_stream` 都在序列化器中，所以 `super` 可以正常工作。

---

<div class="post-metadata">

### Author: ![pangbo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pangbo/32/538562_2.png) [@pangbo](https://meta.discourse.org/u/pangbo)
#### Post date: [2025年十二月5日 14:41 UTC](https://meta.discourse.org/t/why-does-calling-super-in-postserializer-raw-cause-a-500-error-while-calling-object-raw-works/390455/3 "2025-12-05T14:41:23Z")

</div>

这是 Ruby 的一个特性。当你使用 `class ::PostSerializer` 时，你是在 **覆盖** 原始类中的定义，而不是继承它。因为你没有继承 `PostSerializer`，所以 `super` 找不到相应的方法。

你应该使用 `prepend` 而不是重新打开一个已定义的类。

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [2025年十二月5日 15:18 UTC](https://meta.discourse.org/t/why-does-calling-super-in-postserializer-raw-cause-a-500-error-while-calling-object-raw-works/390455/4 "2025-12-05T15:18:04Z")

</div>

> [@copymonopoly](#):
>
> 我正在学习如何扩展 Discourse 序列化器（serializer）

您想改用 `add_to_serializer`。

例如：[How to add user data to the post serializer?](https://meta.discourse.org/t/how-to-add-user-data-to-the-post-serializer/143523)

---

<div class="post-metadata">

### Author: ![copymonopoly](https://avatars.discourse-cdn.com/v4/letter/c/4491bb/32.png) [@copymonopoly](https://meta.discourse.org/u/copymonopoly)
#### Post date: [2025年十二月5日 18:24 UTC](https://meta.discourse.org/t/why-does-calling-super-in-postserializer-raw-cause-a-500-error-while-calling-object-raw-works/390455/5 "2025-12-05T18:24:56Z")

</div>

感谢您的解释！  
您说得对——重新打开 `::PostSerializer` 是问题所在。改用 `prepend` 后，一切都按预期工作了。

我现在使用的是这个模块：

```plaintext
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

```

这在我这边完美运行。再次感谢您的指导！

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [2025年十二月5日 18:47 UTC](https://meta.discourse.org/t/why-does-calling-super-in-postserializer-raw-cause-a-500-error-while-calling-object-raw-works/390455/6 "2025-12-05T18:47:34Z")

</div>

没有 🙄 那不是正确的方法

> [@RGJ](#):
>
> 你想改用 `add_to_serializer`。

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2025年十二月5日 19:58 UTC](https://meta.discourse.org/t/why-does-calling-super-in-postserializer-raw-cause-a-500-error-while-calling-object-raw-works/390455/7 "2025-12-05T19:58:30Z")

</div>

哦。对。我知道的。不确定为什么那不是我的答案。🤷

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [2025年十二月5日 20:37 UTC](https://meta.discourse.org/t/why-does-calling-super-in-postserializer-raw-cause-a-500-error-while-calling-object-raw-works/390455/8 "2025-12-05T20:37:25Z")

</div>

从技术上讲，你的答案是正确的，因为它解释了 500 错误。

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [2025年十二月5日 20:39 UTC](https://meta.discourse.org/t/why-does-calling-super-in-postserializer-raw-cause-a-500-error-while-calling-object-raw-works/390455/9 "2025-12-05T20:39:21Z")

</div>

我回答了他问的问题。你回答了他本该问的问题！

但至少我答对了。

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [2026年一月4日 20:40 UTC](https://meta.discourse.org/t/why-does-calling-super-in-postserializer-raw-cause-a-500-error-while-calling-object-raw-works/390455/10 "2026-01-04T20:40:21Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
