Serializers podem ser fornecidos com um parâmetro scope: destinado a fornecer o contexto de permissões para o serializer. No código do Discourse, o escopo fornecido é um Guardian, e parece que todo serializer tem a intenção de receber um Guardian como seu escopo. ApplicationController (a classe base de todos os controllers) mantém um Guardian e possui múltiplos mecanismos para tentar garantir que o Guardian seja injetado como scope: para todos os serializers.
No entanto, nem todos os cenários são cobertos por esses mecanismos. Sempre que um serializer é explicitamente construído, por exemplo, chamadas para ActiveModel::ArraySerializer.new(...), o escopo precisa ser injetado manualmente. De fato, a maioria das instâncias de XxxxSerializer.new(...) tem um scope: scope ou scope: guardian na lista de argumentos. Mas, nem todas.
Então, minha pergunta: qual é a filosofia de desenvolvimento aqui? É:
- O escopo deve simplesmente ser sempre encaminhado (a menos que haja uma razão específica para não o fazer); se alguém esqueceu de fazer isso, é um bug à espera de acontecer e deve ser corrigido com um
scope: ...apropriado adicionado; OU - Sim, tudo bem; alguém pode corrigir esses pontos à medida que surgem, quando eles realmente quebram algo para alguém.
No meu caso, adicionei um uso de scope a BasicUserSerializer… e então fiquei muito perplexo quando descobri que isso quebrou coisas no Chat… o que finalmente percebi (depois de muita investigação) foi o resultado de algum serializer enterrado em uma cadeia XxxSerializer -> YyySerializer -> ... -> BasicUserSerializer não encaminhando o escopo!