Perché chiamare super in PostSerializer#raw causa un errore 500 mentre chiamare object.raw funziona?

Ciao a tutti,

Sto imparando come estendere i serializer di Discourse e mi sono imbattuto in un comportamento che non capisco del tutto.

Ho aggiunto questo codice per sovrascrivere 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

Questo funziona perfettamente.

Tuttavia, se lo modifico per usare super:

require_dependency "post_serializer"

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

Quando scope.can_edit?(object) è vero, la chiamata a super causa un errore 500 per /posts/:id.json.

So che posso evitare il problema usando object.raw invece di super, ma voglio capire perché super causa un’eccezione in questo caso, specialmente perché sovrascrivo anche altri metodi (cooked, post_stream, ecc.) e super funziona bene in quei casi.

Dato che sono ancora nuovo agli interni di Discourse, apprezzerei molto una spiegazione su:

  • a cosa si risolve super all’interno di PostSerializer#raw,
  • perché chiamare super in questo caso porta a un errore 500,
  • e perché raw si comporta diversamente rispetto a metodi come cooked.

Grazie in anticipo per qualsiasi aiuto!

Sono abbastanza sicuro che sia perché raw non è nel serializzatore per un post normale. Viene incluso solo quando si modifica. Per visualizzare un post è necessario solo cooked; sarebbe uno spreco includere anche raw quando non è necessario.

cooked e post_stream sono nel serializzatore, quindi super funziona.

Questa è una funzionalità di Ruby. Quando usi class ::PostSerializer, stai sovrascrivendo la definizione nella classe originale invece di ereditarla. Poiché non stai ereditando da PostSerializer, super non riesce a trovare il metodo corrispondente.

Dovresti usare prepend invece di riaprire una classe già definita.

4 Mi Piace

Vuoi usare add_to_serializer invece.

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

Grazie per la spiegazione!
Hai ragione: riaprire ::PostSerializer era il problema. Dopo essere passato a prepend, tutto funziona come previsto.

Ora sto usando questo modulo:

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

Questo funziona perfettamente da parte mia. Grazie ancora per la guida!

No :roll_eyes: non è così

[quote=“RGJ, post:4, topic:390455”]Vuoi usare add_to_serializer invece.
[/quote]

2 Mi Piace

Oh. Giusto. Lo sapevo. Non sono sicuro del perché non sia stata la mia risposta. :person_shrugging:

2 Mi Piace

Tecnicamente, la tua risposta era quella corretta, dato che spiega l’errore 500.

1 Mi Piace

Rispondo alla domanda che ha fatto. Hai risposto alla domanda che avrebbe dovuto fare!

Ma almeno ho indovinato.

1 Mi Piace