A fronteira que já existe

Prévia grátis 4 min de leitura

O padrão repositório serve para manter o acesso a dados longe de todo o resto. Antes de julgá-lo, meça quanto disso esta aplicação já tem. Os números abaixo foram medidos em 28/09/2026.

A medição

objetos de consulta:                     58
dos quais definem um Result de Data:     51
chamadas do ActiveRecord em views:        0
chamadas do ActiveRecord em controllers: 22
objetos de serviço:                      55

Não há acesso a dados na camada de view, em nenhum dos 100 templates. É esse o resultado que costuma vender o padrão repositório, e esta aplicação chegou a ele sem repositório.

Vinte e duas chamadas ficam em controllers, em 57 arquivos de controller. A lição 5 as separa por tipo.

Como é um objeto de consulta aqui

module Catalog
  class ListCoursesQuery
    Result = Data.define(:courses_by_level, :lesson_counts, :total_counts_by_level)

    def self.call(authenticated: true)
      courses = ::Catalog::Course.active.ordered.includes(:category)
      ...
    end
  end
end

Um método de classe, argumentos nomeados e um objeto Data como retorno. Cinquenta e um dos cinquenta e oito seguem esse formato, e nenhum devolve uma relação.

A parte que não é o que parece

O courses_by_level guarda registros de Catalog::Course. O objeto Data é um contêiner para models do ActiveRecord e não os substitui.

Isso é de propósito. O MEMORY.md diz com todas as letras:

"Consultas precisam devolver objetos Data puros ou Arrays de Models do ActiveRecord. São operações puramente de Domínio e nunca devem conter lógica de apresentação, formatação de HTML, ou roteamento de URL."

A regra proíbe lógica de apresentação e permite ActiveRecord. É uma posição clara, e diferente da do padrão repositório. As duas se confundem com frequência, por isso vale deixar claro.

flowchart TB
  V["views: 0 chamadas de acesso a dados"] --> B["a fronteira que importa"]
  C["controllers: 22 chamadas em 57 arquivos"] --> B
  Q["58 objetos de consulta, 51 com Result de Data"] --> B
  Q --> N["o objeto Data contém models do ActiveRecord"]
  N --> P["uma fronteira de formato, não de persistência"]

Duas fronteiras diferentes

Essa distinção atravessa o curso inteiro.

Uma fronteira de formato define o que quem chama recebe: três campos nomeados, em vez do que um controller por acaso atribuiu. Quem chama não alcança nada que não tenha recebido, e o contrato da consulta cabe numa linha.

Uma fronteira de persistência esconde de quem chama a origem dos dados. Ela devolve objetos de domínio sem save, sem where e sem associações para percorrer.

Esta aplicação tem a primeira em todo lugar e a segunda em lugar nenhum. Um controller com courses_by_level na mão tem registros de Course, e poderia chamar .update! em qualquer um.

O que cada uma entrega

Fronteira de formato Fronteira de persistência
Acesso a dados fora das views Sim Sim
O contrato da consulta é legível Sim Sim
Quem chama pode percorrer para qualquer coisa Sim, pode Não
Trocar o ORM Não Em princípio
Testar o domínio sem banco Não Sim
Custo Uma linha de Data.define Uma camada de mapeamento por agregado

A maioria dos times quer as duas primeiras linhas, e um objeto de consulta já as entrega de graça.

As linhas três, quatro e cinco são território do padrão repositório. A lição 2 pergunta quanto vale cada uma numa aplicação Rails, porque as respostas mudam em relação à linguagem para a qual o padrão foi escrito.

Onde isso deixa a base de código

Esta base resolveu o problema do padrão repositório com uma ferramenta mais barata e abriu mão de uma propriedade.

Qual: um Course entregue a um controller continua sendo um Course. Ele é mutável, dá para percorrer suas associações e segue ligado ao banco. Se isso importa é a pergunta em aberto, e as lições 3 a 6 respondem de quatro jeitos.

A medição, essa não está em discussão. Nenhum acesso a dados em 100 templates é uma fronteira real, e quem a garantiu foi uma convenção, não uma abstração.

Pontos-chave

  • Medido em 28/09/2026: 58 objetos de consulta, 51 com Result de Data, 0 chamadas de acesso a dados em views, 22 em controllers.
  • O Result de Data contém models do ActiveRecord. É fronteira de formato, não de persistência.
  • O MEMORY.md proíbe lógica de apresentação em consultas e permite explicitamente devolver models.
  • Uma fronteira de formato dá contratos legíveis e tira o acesso a dados das views. Uma de persistência esconde o ORM.
  • Esta base tem a primeira em todo lugar e a segunda em lugar nenhum, por convenção e não por abstração.
Aula 1 de 7 · grátis

Continue com a aula 2

O que o padrão promete

Revisa as quatro promessas do padrão e o atrito de empilhar Data Mapper sobre Active Record no Rails.

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

Digite para buscar...