Posted on: March 24, 2026 05:49 PM
Posted by: Renato
Views: 83
Evolução no Eloquent: Dominando a Nova Sintaxe de Attributes no Laravel
Se você trabalha com Laravel há algum tempo, certamente está familiarizado com os métodos getSomeAttribute e setSomeAttribute. Embora funcionais, eles espalhavam a lógica de um único campo por dois métodos diferentes. Com a chegada das versões mais recentes (Laravel 9, 10 e 11), essa abordagem foi substituída por uma sintaxe muito mais coesa, poderosa e performática.
O Que Mudou?
A nova abordagem utiliza a classe Illuminate\Database\Eloquent\Casts\Attribute. Em vez de dois métodos, agora definimos apenas um, com o nome da propriedade em camelCase, retornando uma instância de Attribute.
O Padrão Antigo (Legacy)
No modelo antigo, para mapear um campo virtual chamado stock_quantity para a coluna stock no banco, fazíamos:
public function getStockQuantityAttribute(): ?int
{
return $this->getAttribute('stock');
}{
$this->setAttribute('stock', $value);
}
Essa mudança na sintaxe, introduzida no Laravel 9, é um dos avanços mais elegantes do Eloquent recentemente. Ela substitui o padrão antigo de prefixos get...Attribute e set...Attribute por uma única definição unificada usando a classe Illuminate\Database\Eloquent\Casts\Attribute.
Aqui está o que você precisa saber sobre essa evolução:
1. O que mudou na estrutura?
Antes, você precisava de dois métodos distintos para manipular um atributo. Agora, você define um único método com o nome do atributo (em camelCase) que retorna um objeto do tipo Attribute.
Exemplo Comparativo
-
Antigo:
getFirstNameAttribute()esetFirstNameAttribute($value) -
Novo:
firstName(): Attribute
2. Principais Vantagens
A nova sintaxe não é apenas estética; ela traz funcionalidades poderosas que antes eram complexas de implementar:
-
Unificação: O comportamento de leitura (get) e escrita (set) fica no mesmo bloco lógico.
-
Caching (
shouldCache()): Como visto no seu exemplocombinationLabel, você pode encadear o métodoshouldCache(). Isso é excelente para atributos calculados complexos, pois o Laravel armazena o resultado na memória da instância do objeto durante o ciclo de vida da requisição, evitando reprocessamento. -
Acesso a outros atributos: O fechamento (
closure) dogetrecebe um segundo argumento$attributes, permitindo acessar outros campos do modelo sem disparar novas consultas ou depender do estado interno de forma arriscada.
O Padrão Moderno (Laravel 11+)
A mesma funcionalidade, agora centralizada e utilizando as facilidades do PHP 8.2+:
protected function stockQuantity(): Attribute
{
return Attribute::make(
get: fn (?int $value, array $attributes): ?int => $attributes['stock'] ?? null,
set: fn (?int $value): array => ['stock' => $value],
);
}Por que migrar para a nova sintaxe?
1. Centralização Lógica
A maior vantagem é visual e organizacional. O "Acessor" (get) e o "Mutator" (set) residem no mesmo bloco de código. Isso facilita a manutenção e evita que você esqueça de atualizar uma ponta ao modificar a outra.
2. Cache Nativo com shouldCache()
Um dos recursos mais subestimados é a capacidade de cachear o resultado de atributos calculados. Imagine um atributo que formata strings complexas ou percorre coleções, como o seu exemplo combinationLabel:
public function combinationLabel(): Attribute
{
return Attribute::make(
get: function () {
// Lógica complexa de ordenação e pluck
return $this->variationValues
->sortBy(fn ($v) => $v->variation->position)
->pluck('value')
->implode(' / ');
}
)->shouldCache(); // O resultado é memorizado durante o ciclo da requisição
}Sem o shouldCache(), cada vez que você chamasse $product->combination_label, o Laravel executaria toda a lógica de ordenação e mapeamento novamente. Com ele, o resultado é guardado na memória após a primeira execução.
3. Acesso Seguro ao Array de Atributos
A nova sintaxe passa o array $attributes como segundo argumento para as Closures. Isso resolve o problema de tentar acessar um atributo que ainda não foi carregado ou evitar loops infinitos ao chamar $this->attribute dentro do próprio método.
Métodos de Casts Dinâmicos
Acompanhando essa mudança, o Laravel 11 introduziu o método casts() em substituição à propriedade protegida $casts. Isso permite que você utilize lógica dentro da definição dos tipos:
protected function casts(): array
{
return [
'price' => 'decimal:2',
'active' => 'boolean',
'created_at' => 'datetime',
];
}Conclusão
A nova sintaxe de Attributes não é apenas "perfumaria". Ela traz:
-
Código mais limpo (utilizando Arrow Functions).
-
Melhor performance (com cache nativo).
-
Tipagem forte (totalmente compatível com PHPStan e ferramentas de análise estática).
Ao atualizar seus modelos para este padrão, você garante que sua aplicação esteja alinhada com as melhores práticas de engenharia de software do ecossistema Laravel moderno.
Donate to Site
Renato
Developer