Se você já teve algum contato com Ruby, já deve ter ouvido falar sobre o ActiveRecord, a gem que usamos pra fazer operações no banco de dados de forma mais fácil. Pra mais detalhes, é só dar uma olhada neste post.

Mas hoje a gente vai conversar sobre o padrão Active Record que nada mais é do que um padrão de arquitetura de software, no qual, como você deve imaginar, a gem ActiveRecord é baseada nesse padrão.

Antes de tudo, vamos entender o que é esse padrão.

O que é o Padrão Active Record?

O Active Record é um padrão arquitetural que, segundo Martin Fowler, em seu livro Patterns of Enterprise Application Architecture, é um objeto que representa uma linha de uma tabela, encapsula o acesso ao banco e adiciona lógica de domínio aos dados.

Beleza, mas o que isso quer dizer?!

No padrão Active Record, o objeto vai concentrar as duas coisas, dados e comportamentos. Além disso, ele vai ser um espelho de uma linha da tabela em um banco de dados.

Dessa forma, o objeto funciona como a interface entre a aplicação e o banco de dados permitindo realizar operações no banco por meio do próprio objeto, já que cada instância corresponde diretamente a uma linha da tabela. Assim, o objeto vai ser o meio de consultar, inserir, atualizar e excluir no banco.

Eu sei que você deve tá pensando que é isso que a gente faz quando usamos Ruby on Rails (RoR). E sim, a gente faz por o RoR adotou justamente esse padrão e o utiliza muito bem como base pra seus models.

Além do Rails, tem vários outros frameworks que utilizam esse padrão, como o Django e Laravel.

O que o Active Record resolve?

Quando trabalhamos com POO e com banco de dados, estamos lidando com dois mundos diferentes, isso porque o banco relacional trabalha com linhas e tabelas, enquanto o POO trabalha com classes e objetos.

Então, pra lidar com esse problema, o Active Record propõe justamente conectar objetos ao banco de dados de forma simples e intuitiva. Isso abstrai a necessidade de escrever SQL diretamente na maior parte dos casos.

Com isso, de maneira geral, o padrão cria uma “ponte” entre o modelo de orientação a objetos e a estrutura relacional do banco de forma que a classe representa uma tabela, o objeto (instância) representa uma linha da tabela e os atributos do objeto representam as colunas da tabela.

Vamos imaginar um e-commerce onde temos no banco as tabelas orders e order_items.

Orders:

id customer_name total_amount status
1 Aline 250.00 pending

Order Items:

id order_id product_name quantity price
1 1 Notebook 1 200
2 1 Mouse 1 50

No padrão Active Record, isso poderia ser representado assim:

class Order
  # Atributos representando as colunas da tabela
  attr_accessor :id, :customer_name, :total_amount, :status

  # Comportamentos
  def total
    total_amount
  end

  def mark_as_paid
    self.status = "paid"
  end
end

class OrderItem
  attr_accessor :id, :order_id, :product_name, :quantity, :price

  def subtotal
    quantity * price
  end
end

Além da correspondência da estrutura, existe outro ponto importante no Active Record: a persistência dos dados.

Até agora, falamos apenas da relação entre classe e tabela. Mas o padrão vai além disso.

E aqui vale deixar claro: estamos falando do Active Record como conceito arquitetural, não da implementação específica do Rails.

No padrão, o próprio objeto também sabe como salvar a si mesmo no banco.

Isso significa que, se você criar um Order, é o próprio objeto Order que vai saber como inserir ou atualizar aquele registro na tabela. Não existe, necessariamente, uma classe separada só para fazer isso.

Ou seja, o modelo não guarda apenas os dados, ele também sabe como persistir esses dados.

class Order
  attr_accessor :id, :customer_name, :total_amount, :status

  def save
    # aqui entraria a lógica para inserir ou atualizar no banco
  end
end

Nesse caso, o método save estaria dentro da própria classe. É isso que caracteriza o padrão: o objeto não depende de outra camada para ser persistido, ele mesmo assume essa responsabilidade.

Quando o Active Record funciona bem

Agora que já entendemos o conceito e o problema que o Active Record resolve, precisamos conversar sobre quando esse padrão realmente brilha.

O Active Record funciona muito bem em aplicações centradas em dados, o que, convenhamos, é a maioria dos sistemas web hoje em dia.

Por exemplo:

  • Um e-commerce, onde você precisa gerenciar produtos, pedidos e usuários.

  • Um sistema de gestão interna, como controle de clientes, contratos ou faturas.

  • Uma aplicação de blog, com posts, comentários e categorias.

  • Um sistema de cadastro, como CRM ou plataforma educacional.

Em todos esses casos, a maior parte das operações gira em torno de criar, consultar, atualizar e remover registros. Como o modelo já concentra dados e persistência, a estrutura da aplicação fica simples e direta. Você cria um objeto, altera seus atributos e salva.

Agora, isso não quer dizer que o Active Record seja a única forma de resolver esse problema. Ele funciona muito bem em muitos cenários, mas dependendo da complexidade do sistema, outras abordagens podem fazer mais sentido.

Quando o Active Record não é indicado

Existem algumas críticas ao Active Record, e quase todas giram em torno da mesma ideia: ele funciona muito bem quando a estrutura do sistema se parece bastante com a estrutura do banco.

Ou seja, quando cada model representa diretamente uma tabela e as regras de negócio estão bem próximas dos próprios dados.

O problema é que nem sempre o mundo é tão organizado assim.

Conforme a aplicação cresce, o domínio começa a ficar mais complexo e já não encaixa tão perfeitamente na estrutura das tabelas. Você começa a precisar de objetos que representam conceitos do negócio, e que não correspondem diretamente a uma única tabela no banco.

E aí o que acontece? O model começa a virar o lugar onde tudo vai parar.

Quando o model começa a fazer coisa demais

Se você já trabalhou em um projeto Rails maior, talvez já tenha visto isso:

  • models com dezenas de métodos

  • vários callbacks encadeados

  • validações condicionais complexas

  • regras diferentes dependendo do contexto

  • lógica que não tem nada a ver com persistência

Nesse momento, o model deixa de ser apenas um “espelho da tabela” e vira quase um centro de comando da aplicação.

Isso acontece porque, no Active Record, estado, persistência e regra vivem juntos.

Testabilidade

Outro ponto que costuma aparecer é a testabilidade.

Como o model já está diretamente ligado ao banco, muitas vezes você precisa de banco até para testar regras que são puramente de negócio.

Não é impossível testar (Rails facilita bastante isso), mas o acoplamento existe.

Quando o domínio não é igual ao banco

Active Record assume que sua modelagem de objetos está bem alinhada com sua modelagem relacional.

Mas quando o domínio começa a ficar mais sofisticado, essa correspondência direta pode começar a ficar forçada.

E aí surgem gambiarras para “encaixar” o modelo de negócio na estrutura do banco.

Isso não significa que o Active Record seja um erro ou uma má escolha. Significa apenas que ele faz uma escolha arquitetural clara: prioriza simplicidade e proximidade com o banco. Em muitos cenários isso é excelente. Em outros, pode exigir mais cuidado na organização do código.

Por que ainda vale entender esse padrão?

Talvez você esteja pensando: “Tá, mas hoje em dia o Rails já faz tudo isso. Então pra que eu preciso saber que isso é um padrão?”

E é uma dúvida totalmente válida.

A verdade é que o Rails não inventou o Active Record. Ele se inspirou em algo que já existia como decisão arquitetural. O padrão veio antes dos frameworks que a gente usa hoje.

Na época, a preocupação era organizar melhor a forma como as aplicações acessavam o banco de dados, especialmente em sistemas maiores.

Então quando a gente entende o padrão, a gente começa a perceber que o Rails não faz as coisas “porque sim”. Ele faz porque alguém, lá atrás, tomou uma decisão arquitetural específica.

E entender essa decisão muda a forma como a gente pensa arquitetura.

Mesmo que você nunca implemente um Active Record “na mão”, saber o que está por trás ajuda a enxergar os limites da abordagem e a não tratar framework como mágica.

Ah e caso você tenha interesse em aprofundar sobre esse e outros padrões, o livro de Martin Fowler pode ajudar.

Até a próxima!