A convenção de engine que já está aqui
Quatro arquivos desta aplicação declaram uma convenção de engine do Rails. Vinte e três models recusam essa convenção. Esse é todo o ponto de partida.
A declaração
# app/models/catalog.rb
module Catalog
def self.table_name_prefix
"catalog_"
end
end
Quatro namespaces fazem isso, Catalog, Community, Enrollment e Partners, e cada um define um prefixo. O Identity declara o módulo e nenhum prefixo.
O table_name_prefix é o idioma de engine do Rails. É o que o isolate_namespace configura para você, e serve para impedir que as tabelas de uma engine colidam com as da aplicação que a hospeda. Adotá-lo num monolito é adotar uma convenção de engine sem ter uma engine. Isso é razoável: uma tabela catalog_courses diz qual contexto é dono dela.
O que acontece na prática
USA o prefixo (1):
Community::Comment -> community_comments
SOBRESCREVE (23):
Catalog::Category -> categories
Catalog::Challenge -> challenges
Catalog::Course -> courses
Catalog::Lesson -> lessons
Catalog::Quiz -> quizzes
Catalog::QuizOption -> quiz_options
Catalog::QuizQuestion -> quiz_questions
Enrollment::Badge -> badges
Enrollment::Bookmark -> bookmarks
Enrollment::Enrollment -> enrollments
Enrollment::ExperiencePoint -> experience_points
Enrollment::LessonCompletion -> lesson_completions
Enrollment::LessonNote -> lesson_notes
Enrollment::Level -> levels
Enrollment::QuizAttempt -> quiz_attempts
Enrollment::UserBadge -> user_badges
Partners::ApiToken -> partner_api_tokens
Partners::CourseSponsorship -> partner_course_sponsorships
Partners::HandoffNonce -> partner_handoff_nonces
Partners::Inquiry -> partner_inquiries
Partners::Partner -> partners
Partners::Referral -> partner_referrals
Partners::Role -> partner_roles
Cada um desses vinte e três declara self.table_name explicitamente, e um nome de tabela explícito vence o prefixo.
Um model em vinte e quatro segue a convenção, e segue por não mencioná-la. O Community::Comment não tem a linha self.table_name, então o prefixo vale e a tabela é community_comments.
flowchart TB
A["4 namespaces declaram table_name_prefix"] --> B["o idioma de engine do Rails, num monólito"]
B --> C["23 models declaram self.table_name e sobrescrevem"]
B --> D["1 model omite e fica com prefixo"]
D --> E["Community::Comment -> community_comments"]
C --> F["a convenção foi adotada, e recusada, um model por vez"]
Do que isso é evidência
Não é um bug. Todos esses vinte e três nomes estão corretos: courses, lessons e enrollments são bons nomes de tabela, e catalog_courses seria pior de digitar numa sessão do psql.
É evidência de uma convenção adotada sem uma decisão por trás. O enquadramento do curso de nível Pleno "Liderança: processo ADR" se aplica em cheio: as declarações de prefixo dizem o que fazer, nada diz por quê, e então quem escreveu cada model decidiu de novo, vinte e quatro vezes, e chegou à mesma resposta vinte e três vezes.
A única exceção também não parece uma discordância. O Community::Comment foi escrito em 30 de agosto, no mesmo dia dos quatro primeiros models do Partners, e todos esses declaram o nome da tabela. Nada no código diz por que este não declara.
Esse é o achado real: a nomenclatura atual das tabelas não é uma convenção. É o que sobrou de vinte e três decisões independentes e uma omissão.
As três opções honestas
Apagar as declarações de prefixo. Elas só têm efeito em um model de vinte e quatro, e no resto apenas levam quem lê a achar que as tabelas têm prefixo. Renomeie community_comments para comments e a base de código fica consistente.
Seguir as declarações. Apague as vinte e três linhas de self.table_name, escreva vinte e três migrações de renomeação, e toda tabela passa a anunciar o seu contexto. É caro, e deixa o esquema autodescritivo.
Deixar como está e registrar qual das duas é a verdade. Uma linha no MEMORY.md, um ADR: "as tabelas têm o nome do que guardam, não do contexto; as declarações de table_name_prefix são vestigiais."
Qualquer uma das três é melhor do que deixar isso sem registro, porque senão quem lê perde dez minutos toda vez que se pergunta se uma tabela tem prefixo, e a resposta é "em geral não, com uma exceção".
Esta aplicação ficou com a terceira opção em 2026-09-28. O MEMORY.md agora diz que as tabelas têm o nome do que guardam, que um model novo declara self.table_name e que as quatro declarações são vestigiais.
Por que isso abre um curso sobre engines
A pergunta por baixo é a que o curso inteiro faz: quanto do modelo de engine você quer, e quanto custa cada peça?
Esta aplicação pegou uma peça, o prefixo de tabela, e depois a rejeitou na prática. É uma resposta específica para uma pergunta específica, dada sem que ninguém enunciasse nenhuma das duas. A lição 2 mostra o resto do modelo.
Pontos-chave
- Quatro namespaces declaram
table_name_prefix, o idioma de engine do Rails para evitar colisão de tabelas. - Medido em 2026-09-28: 23 models sobrescrevem o prefixo com um
self.table_nameexplícito; só 1 o segue, por omissão. - Nenhum dos vinte e três nomes está errado; é uma convenção adotada sem uma decisão por trás.
- Três opções honestas: apagar as declarações, segui-las ou registrar qual é a verdade.
- Hoje quem lê perde dez minutos sempre que se pergunta se as tabelas têm prefixo.
Continue com a aula 2
O que uma engine de fato é
Uma engine é uma aplicação Rails dentro de outra; o isolate_namespace evita colisão de nomes, mas permite qualquer referência.
Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.