Eloquent Mutators e Casting

Laravel
Tempo de leitura: 5 minutos

Eloquent Mutators e Casting: Ao trabalhar com o Eloquent ORM no Laravel, frequentemente nos deparamos com a necessidade de formatar ou transformar dados antes de armazená-los no banco de dados ou após recuperá-los. O Eloquent oferece dois recursos poderosos para lidar com essas transformações: eloquent mutators (mutadores) e eloquent casting (conversão de atributos). Mutators permitem modificar atributos antes da persistência, enquanto casting define como os atributos são convertidos entre o banco de dados e o seu model.

Este artigo explora em detalhes esses recursos, fornecendo exemplos práticos e abrangentes.

Accessors e Mutators

Accessors e mutators são métodos que permitem interceptar e modificar os valores dos atributos do seu model Eloquent antes de serem retornados (accessors) ou antes de serem armazenados no banco de dados (mutators).

  • Accessors

Um accessor formata um atributo quando ele é acessado. O nome do método deve seguir a convenção get{NomeDoAtributo}Attribute.

Exemplo:

Suponha que você tenha um atributo nome_completo que armazena o nome completo de um usuário, mas você quer acessar separadamente o primeiro nome e o sobrenome.

PHP

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function getPrimeiroNomeAttribute()
    {
        return explode(' ', $this->nome_completo)[0];
    }

    public function getSobrenomeAttribute()
    {
       $nomes = explode(' ', $this->nome_completo);
       return end($nomes); // Pega o último elemento do array, que será o sobrenome
    }

    public function getNomeComPrefixoAttribute(){
        return "Sr(a). " . $this->nome_completo;
    }
}

Utilização:

PHP

$user = User::find(1);

echo $user->primeiro_nome; // Exibe o primeiro nome
echo $user->sobrenome; // Exibe o sobrenome
echo $user->nome_com_prefixo; // Exibe "Sr(a). Nome Completo"
  • Mutators

Um mutator modifica um atributo antes de ser armazenado no banco de dados. O nome do método deve seguir a convenção set{NomeDoAtributo}Attribute.

Exemplo:

Suponha que você queira armazenar os nomes em letras maiúsculas no banco de dados.

PHP

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    public function setNomeCompletoAttribute($value)
    {
        $this->attributes['nome_completo'] = strtoupper($value);
    }
}

Utilização:

PHP

$user = new User;
$user->nome_completo = 'joão da silva';
$user->save(); // No banco de dados, 'nome_completo' será armazenado como 'JOÃO DA SILVA'

Você pode usar o mesmo mutator para formatar dados antes de salvar no banco, como por exemplo, formatar um número de telefone, remover espaços em branco, etc.

Attribute Casting

O eloquent casting permite converter atributos para tipos de dados específicos do PHP quando eles são recuperados do banco de dados e vice-versa. Isso simplifica o trabalho com datas, booleanos, arrays e outros tipos de dados.

Você define os castings na propriedade $casts do seu model.

Tipos de Casting Disponíveis:

  • integer: Converte o valor para um inteiro.
  • real ou float: Converte o valor para um número de ponto flutuante.
  • double: Converte o valor para um número de ponto flutuante de precisão dupla.
  • string: Converte o valor para uma string.
  • boolean: Converte o valor para um booleano.
  • object: Converte o valor para um objeto PHP stdClass.
  • array: Converte o valor para um array PHP.
  • collection: Converte o valor para uma instância de Illuminate\Support\Collection.
  • date: Converte o valor para uma instância de Illuminate\Support\Carbon (para datas).
  • datetime: Converte o valor para uma instância de Illuminate\Support\Carbon (para data e hora).
  • timestamp: Converte o valor para um timestamp Unix.
  • encrypted: Criptografa/descriptografa o valor usando o encriptador do Laravel.
  • decimal:n: Converte o valor para um número decimal com n casas decimais.

Exemplo:

PHP

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    protected $casts = [
        'preco' => 'float',
        'estoque' => 'integer',
        'disponivel' => 'boolean',
        'data_lancamento' => 'datetime',
        'configuracoes' => 'array',
    ];
}

Utilização:

PHP

$product = Product::find(1);

if ($product->disponivel) { // $product->disponivel é um booleano
    echo "Produto disponível";
}

echo $product->preco + 10; // $product->preco é um float

echo $product->data_lancamento->format('d/m/Y'); // $product->data_lancamento é um objeto Carbon

var_dump($product->configuracoes); // $product->configuracoes é um array

Custom Casts

Além dos tipos de casting padrão, você pode criar seus próprios casts personalizados para lidar com tipos de dados mais complexos. Isso é feito implementando a interface Illuminate\Contracts\Database\Eloquent\CastsAttributes.

Exemplo:

Suponha que você queira armazenar um endereço como um objeto JSON no banco de dados, mas acessá-lo como um objeto PHP com propriedades específicas.

PHP

<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class Endereco implements CastsAttributes
{
    public function get($model, $key, $value, $attributes)
    {
        if (! $value) {
            return null;
        }

        $endereco = json_decode($value);

        return (object) [
            'rua' => $endereco->rua,
            'numero' => $endereco->numero,
            'cidade' => $endereco->cidade,
            'estado' => $endereco->estado,
            'cep' => $endereco->cep,
        ];
    }

    public function set($model, $key, $value, $attributes)
    {
        if (! $value) {
            return null;
        }

        return json_encode($value);
    }
}

// No Model:

use App\Casts\Endereco;

protected $casts = [
    'endereco' => Endereco::class,
];

Utilização:

PHP

$user = User::find(1);

echo $user->endereco->rua;
echo $user->endereco->cep;

$user->endereco = (object) [
    'rua' => 'Rua Nova',
    'numero' => '123',
    'cidade' => 'São Paulo',
    'estado' => 'SP',
    'cep' => '01000-000',
];

$user->save(); // O endereço será armazenado como JSON no banco de dados

Exemplo Completo: Formatando Preço e Armazenando Status como Booleano

PHP

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Produto extends Model
{
    protected $casts = [
        'preco' => 'decimal:2', // Armazena o preço com 2 casas decimais
        'ativo' => 'boolean',
    ];

    public function getPrecoFormatadoAttribute() {
        return "R$ " . number_format($this->preco, 2, ',', '.');
    }

    public function setNomeAttribute($value){
        $this->attributes['nome'] = strtolower($value);
    }
}

// Utilização:
$produto = new Produto();
$produto->nome = "PRODUTO TESTE";
$produto->preco = 199.99;
$produto->ativo = 1;
$produto->save();

$produtoRecuperado = Produto::find($produto->id);

echo $produtoRecuperado->nome; // produto teste
echo $produtoRecuperado->preco; // 199.99
echo $produtoRecuperado->preco_formatado; // R$ 199,99
var_dump($produtoRecuperado->ativo); // true (booleano)

Conclusão

Eloquent Mutators e Casting: Os eloquent mutators e eloquent casting são recursos essenciais para manipular e formatar dados no Laravel. Mutators permitem transformar dados antes de serem persistidos no banco de dados, enquanto casting define como os dados são convertidos entre o banco de dados e o seu model. A combinação desses recursos oferece grande flexibilidade e controle sobre o fluxo de dados na sua aplicação, resultando em um código mais limpo, organizado e eficiente. O uso de custom casts expande ainda mais as possibilidades, permitindo lidar com tipos de dados complexos de forma elegante.

Dominar esses conceitos é fundamental para qualquer desenvolvedor Laravel que busca construir aplicações robustas e escaláveis. Ao aplicar as técnicas apresentadas neste artigo, você poderá otimizar o processamento de dados e melhorar a manutenibilidade do seu código.

Mas antes de dominar o Laravel, se for o seu caso, toda jornada tem um início. Vamos entender quais são os conhecimentos básicos necessários para aproveitar ao máximo este poderoso framework. Para iniciar seus estudos no Laravel, você precisará dominar as seguintes tecnologias:

HTML
HTML
CSS
CSS
Javascript
JavaScript

E se você gosta do nosso conteúdo, não deixe de contribuir adquirindo os serviços e produtos dos nossos apoiadores e empresas que somos associados:

Hospedagem Hostinger
Ofertas Amazon
Amazon Prime
Author: Thiago Rossi