💻 Exemplos: Capítulo 08: Database Seeders, Factories e Transações (DB::transaction)
Especialização em Backend com PHP & Laravel • Demonstrações Práticas Compiláveis
💻 Exemplo 1 — Factory com Faker e Estados Customizados
<?php
// database/factories/ProdutoFactory.php
namespace Database\Factories;
use App\Models\Produto;
use Illuminate\Database\Eloquent\Factories\Factory;
class ProdutoFactory extends Factory
{
protected $model = Produto::class;
public function definition(): array
{
return [
'nome' => $this->faker->words(3, true),
'sku' => $this->faker->unique()->bothify('PROD-####-??'),
'preco' => $this->faker->randomFloat(2, 10, 500),
'estoque' => $this->faker->numberBetween(0, 200),
'ativo' => true,
];
}
public function esgotado(): static
{
return $this->state(fn (array $attributes) => ['estoque' => 0]);
}
}
💻 Exemplo 2 — Seeder com Relacionamentos em Cascata
<?php
// database/seeders/DatabaseSeeder.php
namespace Database\Seeders;
use App\Models\Cliente;
use App\Models\Pedido;
use App\Models\Produto;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run(): void
{
Produto::factory(50)->create();
Cliente::factory(10)
->has(Pedido::factory()->count(3))
->create();
$this->call([
PerfilAcessoSeeder::class,
]);
}
}
💻 Exemplo 3 — Transação Atômica com Bloqueio Pessimista de Estoque
<?php
// app/Services/PedidoService.php
namespace App\Services;
use App\Models\Pedido;
use App\Models\Produto;
use Illuminate\Support\Facades\DB;
use RuntimeException;
class PedidoService
{
public function criar(array $dadosPedido, array $itens): Pedido
{
return DB::transaction(function () use ($dadosPedido, $itens) {
$pedido = Pedido::create($dadosPedido);
foreach ($itens as $item) {
$produto = Produto::where('id', $item['produto_id'])
->lockForUpdate()
->first();
if ($produto->estoque < $item['quantidade']) {
throw new RuntimeException("Estoque insuficiente para {$produto->nome}");
}
$produto->decrement('estoque', $item['quantidade']);
$pedido->produtos()->attach($produto->id, [
'quantidade' => $item['quantidade'],
'preco_unitario' => $produto->preco,
]);
}
return $pedido;
}, 3); // até 3 tentativas em caso de deadlock
}
}