8. Atualizar o código do modelo Produto

Depois de gerar o modelo, precisamos configurar alguns detalhes como os campos que podem ser atribuídos em massa ($fillable ) e as relações (caso existam). No Laravel o array $fillable define quais os atributos específicos do modelo que podem ser atribuídos em massa, ou seja, quando queremos que certos campos sejam preenchidos através de uma solicitação, precisamos mencioná-los no array $fillable do modelo.

Aqui está um exemplo simples com o modelo Produto:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Produto extends Model
{
    use HasFactory;

    // Define a tabela associada ao modelo (opcional, se o nome da tabela seguir a convenção no plural)
    protected $table = 'produtos';

    // Os atributos que podem ser preenchidos via mass assignment
    protected $fillable = [
        'code', 
        'name', 
        'quantity', 
        'price', 
        'description'
    ];
}

Explicação do código:

  • use HasFactory: Esta trait permite o uso de fábricas para criar instâncias do modelo, facilitando a geração de dados falsos durante os testes.
  • $table = 'produtos';: Define explicitamente a tabela que este modelo manipula. Este passo é opcional, já que o Laravel, por padrão, assume que o nome da tabela é o plural do nome do modelo. Neste caso, o nome da tabela produtos segue a convenção, então esta linha é opcional.
  • $fillable: Define quais colunas podem ser preenchidas em operações de "mass assignment" (atribuição em massa). Neste exemplo, estamos a permitir que code, name, quantity, price e description possam ser atribuídos em massa ao criar ou atualizar um produto.

Converter Tipos de Dados ($casts)

O array $casts permite transformar atributos em tipos de dados comuns, como inteiro, decimal, booleano, entre outros. Isto pode ser útil para garantir que os dados sejam manipulados e armazenados de forma correta. Vamos adicionar algumas conversões ao nosso modelo Produto:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Produto extends Model
{
    use HasFactory;

    // Define a tabela associada ao modelo (opcional, se o nome da tabela seguir a convenção no plural)
    protected $table = 'produtos';

    // Os atributos que podem ser atribuídos em massa
    protected $fillable = [
        'code', 
        'name', 
        'quantity', 
        'price', 
        'description'
    ];

    protected $casts = [
        'price' => 'decimal:2',
        'quantity' => 'integer',
    ];
}

Neste exemplo, estamos a garantir que o campo price será armazenado com duas casas decimais e que quantity será sempre um valor inteiro.

Conceito de Accessors e Mutators

Os Accessors e Mutators no Laravel são utilizados para modificar valores de atributos de um modelo quando são acedidos ou atribuídos. Eles permitem a manipulação dos dados antes de os armazenar na base de dados ou exibi-los ao utilizador. Para definir um accessor/mutator, crie um método protegido no seu modelo para representar o atributo acessível. Este nome de método deve corresponder à representação "camel case" do verdadeiro atributo do modelo subjacente/coluna do banco de dados, quando aplicável.

  • Accessor: Todos os métodos accessor retornam uma instância de Attribute que define como o atributo será acedido e, opcionalmente, modificado. Para o definir deve fornecer o argumento get ao construtor da classe Attribute.
namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class Produto extends Model
{
   ...
     /**
		* Este método garante que, sempre que o nome do produto for recuperado, ele seja retornado em maiúsculas (uppercase).
     */
    protected function name(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => Str::upper($value),
        );
    }
		...
  • Mutator: Serve para modificar os dados quando o atributo é definido. Isto acontece quando está a atribuir um valor ao atributo antes de ele ser guardado na base de dados. Para definir um mutator, deve fornecer o argumento set ao definir seu atributo

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class Produto extends Model
{
    ...
     /**
     * Este método garante que, sempre que um nome for definido, ele será capitalizado, ou seja, com a primeira letra de cada palavra em maiúscula.
     */
    protected function name(): Attribute
    {
        return Attribute::make(
            set: fn (string $value) => Str::ucfirst($value),
        );
    }
		...

Juntando os dois:

    protected function name(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => Str::upper($value),
            set: fn (string $value) => Str::ucfirst($value),
        );
    }

Introdução ao Conceito de Relacionamento entre Modelos

Relacionamentos entre modelos são um aspeto crucial ao trabalhar com bases de dados relacionais. Laravel fornece métodos simples e intuitivos para definir relacionamentos como Um-para-Um, Um-para-Muitos, Muitos-para-Muitos, entre outros.

Exemplo de Relacionamento Um-para-Muitos

Vamos imaginar que cada produto pode ter várias avaliações feitas pelos utilizadores. Podemos definir esta relação no modelo Produto:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Produto extends Model
{
    ...

    public function avaliacoes()
    {
        return $this->hasMany(Avaliacao::class);
    }
}

E no modelo Avaliacao, definiríamos:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Avaliacao extends Model
{
    ...
		
    public function produto()
    {
        return $this->belongsTo(Produto::class);
    }
}

Resumo

Neste capítulo, discutimos como atualizar o modelo Produto no Laravel. Vimos como usar $fillable para definir quais campos podem ser preenchidos, $casts para converter tipos de dados automaticamente, e métodos de getters e setters para manipular os atributos do modelo. Também introduzimos brevemente o conceito de relacionamentos entre modelos, crucial para a integridade e funcionalidade da nossa aplicação.

Links úteis

  • https://laravel.com/docs/11.x/eloquent-mutators
  • https://laravel.com/docs/11.x/eloquent-relationships
<< 7. Definir rotas Índice 9. Atualizar o código no... >>