Criando o próprio cast no Laravel
Já criei um artigo falando o que é o cast no Laravel, e você pode ver ele clicando aqui, e te aconselho muito a ler esse artigo antes de continuar com esse.
Utilizando os casts padrões do Laravel, a “única coisa” que você vai fazer é transformar o tipo de dados, por exemplo de integer para boolean, mas com o nosso próprio cast podemos brincar um pouco mais com esses dados.
Primeiro tenho que te falar como crio o próprio cast, que é bem simples, é só uma classe, isso mesmo, o nosso cast será uma classe, e essas classes ficarão dentro de App/Casts
.
Essa classe tem a seguinte estrutura.
namespace App\Casts; use Illuminate\Contracts\Database\Eloquent\CastsAttributes; class Name implements CastsAttributes { public function get($model, string $key, $value, array $attributes) { // } public function set($model, string $key, $value, array $attributes) { // } }
Veja que criei uma classe chamada Name dentro da pasta Casts que está dentro da pasta App, e essa classe obrigatoriamente tem que implementar a interface CastsAttributes
e com isso utilizar os métodos get e set.
Você tem que ter em mente que o cast serve tanto para ler como gravar, o set e get
são para isso, o set
é para gravar e o get
para ler.
Agora vou “brincar” um pouco com o campo name da tabela users, e vou fazer isso no get, para listar, mas antes preciso te mostrar como faz para chamar esse cast lá na propriedade $casts dentro do Model.
protected $casts = [ 'name' => Name::class ];
Viu como é simples ?Para chamar o nosso cast é somente colocar NomeCast::class
.
Agora voltando para o cast vou trabalhar em cima do método get, que é para listar, mas antes de fazer alguma coisa você precisa saber o que significam cada um dos parâmetros desse método, então vamos a eles.
O primeiro parâmetro é o model, que acho que não precisa de maiores explicações, que é o próprio model onde está a propriedade $casts
.
O segundo é o $key
, que é o índice no array $casts no qual estou colocando essa classe, no exemplo abaixo o $key é o name.
protected $casts = [ 'name' => Name::class ];
O terceiro é o $value
, que é o valor desse campo name, o valor que está la no banco de dados nesse campo.
E por último tem o $attributes
, que são todos os campos da tabela.
Perceba o tanto de coisas que podemos usar para “brincar” como o retorno, eu por exemplo vou colocar um prefixo antes do valor, ficando assim:
namespace App\Casts; use Illuminate\Contracts\Database\Eloquent\CastsAttributes; class User implements CastsAttributes { public function get($model, string $key, $value, array $attributes) { return "CFS_{$value}"; } public function set($model, string $key, $value, array $attributes) { // } }
O resultado vai ser CFS_Nome_da_pessoa
em todos os registros, agora imagine o número de possibilidades.
O outro método é o set, que é usado para quando eu for gravar no banco de dados, e para isso vou utilizar o campo tags do tabela users que é um campo do tipo text, e vou gravar um json.
Mas antes de gravar eu preciso validar, por exemplo, o número de elementos do array que será gravado não pode ser maior que um determinado número.
namespace App\Casts; use Illuminate\Contracts\Database\Eloquent\CastsAttributes; class Tag implements CastsAttributes { public function get($model, string $key, $value, array $attributes) { return json_decode($value); } public function set($model, string $key, $value, array $attributes) { $countElements = count($value); if($countElements > 5){ throw new \Exception("Podem ter somente 5 tags"); } return json_encode($value); } }
Se o número de elementos for maior que 5 lança uma exceção, caso não, retorno o json com json_encode
, assim posso gravar o array no banco de dados a representação desse array, e veja que no set estou dando um json_decode
que é para listar esse array como um array.
Mas e se eu quiser alterar o limite de elementos aceitos no array eu preciso entrar na classe e mudar, e eu não quero isso, eu quero mudar direto na propriedade $casts, fazendo isso:
protected $casts = [ 'tags' => \App\Casts\Tag::class.':3' ];
Eu concatenei ‘:3’ depois da classe, e para resgatar esse valor na classe eu pego no método mágico construtor, assim:
namespace App\Casts; use Illuminate\Contracts\Database\Eloquent\CastsAttributes; class Tag implements CastsAttributes { public function __construct($countLimit) { $this->countLimit = (int)$countLimit; } public function get($model, string $key, $value, array $attributes) { return json_decode($value); } public function set($model, string $key, $value, array $attributes) { $countElements = count($value); if($countElements > $this->countLimit){ throw new \Exception("Podem ter somente {$this->countLimit} tags"); } return json_encode($value); } }
Espero que tenha gostado desse segundo artigo sobre como trabalhar com casts no Laravel, e realmente tenha entendido, e para ver o primeiro artigo sobre o assunto clique aqui.
Se quiser conhecer meu trabalho mais a fundo, visite meu canal no YouTube e se quiser um curso completo de Laravel 8 veja meu curso para iniciantes.
🔥 Canal no YouTube: Ir para o canal no YouTube
🔥 Curso de Laravel 8 para iniciantes: Ir para o curso
🔥 Veja meus cursos disponíveis: Ir para a lista de cursos
0 Comments