Relacionamentos
belongsTo, hasMany, belongsToMany, eager loading com with().
Relacionamentos no MAD são relations Eloquent nativas — métodos no model que retornam
um objeto Illuminate\Database\Eloquent\Relations\*. belongsTo para
N:1, hasMany para 1:N, belongsToMany para N:N via tabela pivot.
belongsTo — N:1
Exemplo real (App\Models\Iam\User):
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class User extends Authenticatable
{
public function unit(): BelongsTo
{
return $this->belongsTo(Unit::class, 'unit_id');
}
public function frontpage(): BelongsTo
{
return $this->belongsTo(Program::class, 'frontpage_id');
}
}
$user = User::find($id);
echo $user->unit->name; // acesso como propriedade — dispara a query na 1ª leitura
hasMany — 1:N
use Illuminate\Database\Eloquent\Relations\HasMany;
class PedidoVenda extends Model
{
protected $connection = 'business';
protected $table = 'pedido_venda';
public function itens(): HasMany
{
return $this->hasMany(PedidoVendaItem::class, 'pedido_venda_id');
}
}
$pedido = PedidoVenda::find($id);
foreach ($pedido->itens as $item) {
echo $item->produto_nome;
}
Acessar
$pedido->itenscomo propriedade é lazy — só dispara a query na primeira leitura, depois reusa o resultado já carregado na instância.
belongsToMany — N:N (com pivot)
Exemplo real (App\Models\Iam\User):
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class User extends Authenticatable
{
public function groups(): BelongsToMany
{
return $this->belongsToMany(Group::class, 'mad_iam_user_group', 'user_id', 'group_id');
}
public function roles(): BelongsToMany
{
return $this->belongsToMany(Role::class, 'mad_iam_user_role', 'user_id', 'role_id');
}
}
$user = User::find($id);
$grupos = $user->groups; // Collection<Group>
// Sincronizar a pivot (substitui o conjunto inteiro)
$user->groups()->sync([1, 2, 3]);
// Anexar/desanexar sem afetar os demais
$user->groups()->attach(4);
$user->groups()->detach(4);
Eager loading — evitando N+1
Cuidado em listagens: acessar
$pedido->cliente->nomedentro de umforeachsem pré-carregar dispara uma query adicional por linha. Usewith()para carregar a relação em lote antes do loop.
// ❌ N+1 — uma query por pedido da listagem
foreach (PedidoVenda::all() as $p) {
echo $p->cliente->nome;
}
// ✅ Eager load — 2 queries no total (pedidos + clientes em lote)
$pedidos = PedidoVenda::with('cliente')->get();
foreach ($pedidos as $p) {
echo $p->cliente->nome;
}
// Múltiplas relações, inclusive aninhadas
$pedidos = PedidoVenda::with(['cliente', 'itens.produto'])->get();
Carregando/sincronizando filhos manualmente
Quando você precisa de controle total (ex.: substituir todos os itens de um pedido):
// Carregar
$itens = $pedido->itens; // ou $pedido->itens()->get() pra encadear filtros
// Substituir — deleta os antigos e insere os novos
DB::connection('business')->transaction(function () use ($pedido, $itensArray) {
$pedido->itens()->delete();
$pedido->itens()->createMany($itensArray);
});
Para smart-sync (atualiza existentes, insere novos, remove sumidos — sem apagar e recriar tudo), use
<mad-detail-form>, que faz isso automaticamente. Veja Detail-form.
Exemplo completo: pedido com itens
class PedidoVenda extends Model
{
protected $connection = 'business';
protected $table = 'pedido_venda';
public function itens(): HasMany
{
return $this->hasMany(PedidoVendaItem::class, 'pedido_venda_id');
}
public function cliente(): BelongsTo
{
return $this->belongsTo(Cliente::class, 'cliente_id');
}
protected function totalCalculado(): Attribute
{
return Attribute::make(
get: fn () => $this->itens->sum('valor_total')
);
}
}
class PedidoVendaItem extends Model
{
protected $connection = 'business';
protected $table = 'pedido_venda_item';
public function produto(): BelongsTo
{
return $this->belongsTo(Produto::class, 'produto_id');
}
}
$pedido = PedidoVenda::with(['cliente', 'itens.produto'])->find(42);
echo $pedido->cliente->nome;
echo $pedido->total_calculado;
foreach ($pedido->itens as $item) {
echo $item->produto->nome . ' — R$ ' . $item->valor_total;
}
Próximos
- Detail-form — smart-sync de relacionamentos via Blade.
- Models Eloquent — API base do model.
- Query Builder — fluent API para queries.
- Callbacks — eventos do model pra sincronizar relacionamentos.