Início
NexoPOS

Definir Dependência de Modelos

A dependência do modelo garante que um modelo não possa ser excluído se ainda estiver sendo usado como referência em outro modelo. Por exemplo, um cliente não pode ser excluído se ainda estiver associado a um pedido, e um produto não pode ser excluído se ainda estiver associado a um item de pedido.

Este recurso tende a proteger a integridade dos seus dados, garantindo a exclusão adequada de entradas para evitar entradas órfãs e ocultas.

Declarando Dependência

A dependência é criada por padrão em cada modelo. Você usará a propriedade “setDependencies”, na qual fornecerá um array com a classe relacionada como chave e outro array para configurar a configuração. Aqui vai um exemplo.

<?php
namespace Modules\YourModules\Models;

use App\Models\NsModel;
use App\Classes\Model;

class Book extends NsModel
{
    public function setDepedencies() {
        return [
            BookChapter::class => Model::dependant(
                local_index: 'id', // the index on Book that will be used as reference
                local_name: 'name', // the attribute that will be used to display the error. e.g "a Storm of Sword cannot be deleted..."
                foreign_index: 'id', // is the relation attribute on the BookChapter class
                foreign_name: 'name', // as for the book, this attribute will be used on the error. e.g "a Storm of Sword cannot be deleted as it's used by Chapter 1"
            )
        ];
    }
}

Usando a Tabela Relacionada como Referência

Às vezes, você quer vincular sua dependência a outra tabela relacionada. Vamos considerar o seguinte cenário. Você tem uma receita que usa produtos como ingredientes. Temos aqui uma tabela intermediária que liga os produtos às tabelas de ingredientes da receita. Tipicamente, essa tabela intermediária não tem nenhum atributo “name”; portanto, usaremos o nome da tabela relacionada.

Aqui está uma estrutura detalhada para este exemplo.

Products
-> name: "Tomato"
-> id: 2

Recipe
->name "Hot Tomato"
->id 1

Ingredient
-> product_id: 2
-> recipe_id: 1

Aqui, precisamos criar uma forma de impedir que Produtos sejam excluídos se estiverem sendo usados como Ingredientes, e precisamos usar o nome da Receita para exibir um erro como: “O Tomate não pode ser excluído porque é uma dependência do Hot Tomato”.

<?php
namespace Modules\YourModule\Models;

use App\Models\NsModel;
use App\Classes\Model;

class Product extends NsMoels
{
    public function setDependencies()
    {
        return [
            Ingredient::class => Model::dependant(
                local_name: 'name', // local attribute to be used for the error on the Product table
                foreign_index: 'product_id', // the attribute on the Ingredient table, which is the middleman table
                related: Model::related( // we define the attribute here
                    model: Recipe::class, // we link the related model Recipe
                    local_name: 'name', // the attribute to be used for the error.
                    local_index: 'id', // the foreign attribute on Recipe. The value is by default "id"
                    foreign_index: 'recipe_id', // the local attribute on Ingredient                
                )
            );
        ];
    }
}

Prefixo para o Nome da Dependência

O erro lançado até agora puxa o nome dos itens e o exibe como sendo dependente. No entanto, talvez você queira dar um contexto para esse nome. No nosso exemplo anterior, não seria legal se, em vez de “Tomate Quente”, pudéssemos usar “Receita: Tomate Quente”? É aí que o “prefixo” no método relacionado é usado.

Você vai definir um argumento nomeado “prefix” para uma função de callback que usa o nome do modelo dependente como parâmetro. A partir daí, você pode retornar qualquer outra string localizada usando esse nome.

Estendendo a Dependência de Outro Modelo

Você não é obrigado a fornecer apenas uma dependência para o seu modelo, mas pode fornecer uma dependência personalizada para outros modelos. Por exemplo, um usuário não pode ser excluído se ainda tiver um livro que ele tenha inserido no sistema.

Para isso, no nosso módulo, vamos registrar essa dependência da seguinte forma:

<?php
namespace Modules\YourModule\Providers;

use Illuminate\Support\Provider as CoreProvider;
use App\Classes\Hook;
use App\Classes\Model;
use App\Models\User;
use Modules\YourModule\Models\Book;

class ServiceProvider extends CoreProvider
{
    public function register()
    {
        Hook::filter( User::method( 'setDependencies' ), function( $dependants ) {
            $dependants[ Book::class ]  =   Model::dependant(
                local_index: 'id',
                local_name: 'name',
                foreign_index: 'user_id',
                foreign_name: 'name'
            );
            
            return $dependants;
        });
    }
}