A convenção de nomes do Rails, e onde este app a quebra

Prévia grátis 3 min de leitura

Uma regra, seguida sem pensar

Todo model que estes cursos tocaram, como Catalog::Course, Enrollment::Enrollment e Identity::User, encontra a própria tabela sem ninguém escrever código de mapeamento, na maior parte das vezes. A regra do Rails é pegar o nome da classe, tirar o módulo (descartar qualquer prefixo Module::), passar para snake_case e pôr no plural. Article vira articles. Essa é a convenção inteira, e é por isso que nenhum curso anterior precisou explicá-la: ela funciona em silêncio sempre que o nome da classe e o da tabela já concordam.

Quando eles deixam de concordar

O módulo Catalog deste app define algo com que a maioria dos namespaces nunca se preocupa:

# app/models/catalog.rb
module Catalog
  def self.table_name_prefix
    "catalog_"
  end
end

Esse único método muda o resultado da convenção para todo model dentro de Catalog::. Uma classe descartável, sem nome de tabela explícito:

class Catalog::ScratchNoOverride < ApplicationRecord
end

Catalog::ScratchNoOverride.table_name
# => "catalog_scratch_no_overrides"

Os mesmos três passos, tirar o módulo, passar para snake_case e pôr no plural, e depois catalog_ na frente porque o módulo em volta pediu. Sozinho, Catalog::Course resolveria para catalog_courses. A tabela de verdade é courses.

A linha que fecha a diferença

A primeira linha dentro de Catalog::Course:

# app/models/catalog/course.rb
class Course < ApplicationRecord
  self.table_name = "courses"
end

Com essa única atribuição, o resultado da convenção deixa de importar para esta classe. self.table_name = não ajusta a convenção; ele substitui o resultado, então o Rails nunca calcula catalog_courses para um model a quem disseram qual tabela usar.

Por que isso importa além de um model

Não é uma correção isolada para Course. Quase todo model dos namespaces Catalog::, Enrollment:: e Partners:: tem a própria linha self.table_name: Catalog::Lesson → "lessons", Enrollment::Enrollment → "enrollments", Partners::Partner → "partners". As linhas não são enfeite. Sem elas, cada uma dessas classes procuraria uma tabela com prefixo que não existe, porque o namespace dela define um table_name_prefix. É esse o problema que self.table_name resolve. O único model que fica sem ela, Community::Comment, é o exemplo da aula 2.

Pontos-chave

  • A convenção de nomes do Rails: tirar o módulo do nome da classe, passar para snake_case, pôr no plural. Article → articles, sem código escrito, desde que nada mude as entradas.
  • O módulo Catalog deste app define self.table_name_prefix devolvendo "catalog_", então um model dentro de Catalog:: sem sobrescrita recebe o prefixo: catalog_scratch_no_overrides.
  • Isso faz o resultado da convenção para Catalog::Course ser catalog_courses, enquanto a tabela de verdade é courses.
  • self.table_name = "courses", a primeira linha de Catalog::Course, substitui o resultado calculado em vez de ajustá-lo, e quase todo model dos namespaces com prefixo tem o mesmo tipo de linha pelo mesmo motivo.
Aula 1 de 7 · grátis

Continue com a aula 2

table_name_prefix: o padrão do namespace

O método table_name_prefix nos módulos de namespace, e como Community::Comment resolve para community_comments por meio dele.

Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.

Digite para buscar...