Model e Registros
Para que o sistema de ordenação funcione corretamente, cada model envolvida deve seguir uma estrutura mínima obrigatória.
Abaixo estão descritas as configurações e implementações necessárias para garantir a compatibilidade com a feature.
1. Trait obrigatória
Toda model que utilizar o sistema de ordenação deve incluir a trait:
Essa trait contém os métodos e comportamentos essenciais para manipular a posição dos registros, incluindo funções de ordenação, reordenação após exclusões e cálculo da próxima posição disponível.
2. Evento deleted com reorder()
É obrigatório que a model implemente o evento deleted, chamando o método reorder() após a exclusão de um registro.
Isso garante que a ordenação seja recalculada automaticamente, mantendo a sequência correta dos itens.
Exemplo:
protected static function boot()
{
parent::boot();
static::deleted(function ($model) {
$model->reorder(); // executa após deletar com sucesso
});
}
Observação:
Se a ordenação possuir níveis (ex: seção → produto), é necessário passar um filtro via Closure como terceiro parâmetro na função reorder(), indicando o escopo onde a reordenação deve ocorrer (por exemplo, dentro da mesma seção).
3. Relacionamentos entre níveis
Quando o módulo utiliza ordenação com múltiplos níveis, cada nível adicional deve possuir uma relação "belongsTo" com o nível imediatamente anterior.
Essa relação é obrigatória para que o sistema saiba a qual contexto o registro pertence e consiga filtrar corretamente antes de aplicar a ordenação.
Exemplo:
Na model do nível 3, deve existir uma relação com o nível 2:
public function nivel2() { return $this->belongsTo(NivelDoi::class, 'nivel_2_id'); }
4. Colunas obrigatórias na tabela
A tabela da model deve conter as seguintes colunas:
| Coluna | Tipo | Obrigatoriedade | Descrição |
|---|---|---|---|
| order | integer | Obrigatória | Define a posição do registro dentro do contexto da ordenação. |
| parent_id | integer | Obrigatória somente quando o tipo de ordenação é recursiva (entre registros da mesma model). | |
| <nome_da_fk> | integer | Obrigatória quando existe mais de um nível (não recursiva). Representa a foreign key que liga ao nível anterior. |
Exemplo:
Em uma ordenação recursiva (ex: categorias com subcategorias), use parent_id.
Em uma ordenação com múltiplos níveis (ex: seção → produto), use a FK correspondente, como secao_id.
Em uma ordenação simples (sem níveis), nenhuma FK adicional é necessária.
5. Definindo a ordem no store
No método store (ou equivalente) do controller, a coluna order deve ser preenchida automaticamente com o próximo valor de ordem disponível, utilizando o método getNextOrder() da trait.
Esse método retorna o próximo valor de posição com base no contexto atual.Se for necessário aplicar um filtro (por exemplo, ordenar apenas dentro de um determinado nível), o método aceita uma Closure como segundo parâmetro:
Exemplo:
Nesse caso, o sistema calcula automaticamente o próximo valor com base em todos os registros existentes no módulo atual.
$model->order = $model->getNextOrder();Exemplo com filtro de nível (recomendado para estruturas hierárquicas):
Quando a ordenação depende de outro nível — como no caso seção → produto, em que os produtos devem ser ordenados apenas dentro de uma determinada seção —é obrigatório utilizar uma Closure para filtrar o contexto antes de calcular a próxima posição.
$model->order = $model->getNextOrder(function ($query) use ($secao_id) {
return $query->where('secao_id', $secao_id);
});