NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

Require the package. The service provider is auto-discovered, and its two hard dependencies — approvals-for-laravel (the approval engine) and enums-for-laravel — install automatically:

composer require roundly-consulting/requests-for-laravel

Migrations

Publish and run the migrations. The package does not auto-load them — publishing copies the requests migration into your database/migrations, where you own it, so a bare php artisan migrate before publishing creates nothing:

php artisan vendor:publish --tag="requests-migrations"
php artisan vendor:publish --tag="approvals-migrations"
php artisan migrate

The package owns the requests table; the approvals, approval_requests, approval_request_stages and approval_delegations tables belong to the approvals engine, so publish its migrations too. Republishing lands on the same file rather than adding a second copy.

Key types — set before migrating

The migrations read the key types once, when they first run. Numeric ids need nothing; for UUID or ULID keys set:

EnvConfigSet it when
REQUESTS_KEY_TYPErequests.key_typeThe models that author requests have UUID or ULID keys.
APPROVALS_KEY_TYPEapprovals.key_typeThe approvers (and every other model the approvals engine points at) have UUID or ULID keys.
REQUESTS_PRIMARY_KEY_TYPErequests.primary_key_typeAlways — to the same value as APPROVALS_KEY_TYPE, since the engine’s subject and approvable columns point at the request id.

A host with UUID authors and approvers sets all three to uuid. Leaving REQUESTS_PRIMARY_KEY_TYPE at bigint under APPROVALS_KEY_TYPE=uuid fails on PostgreSQL (invalid input syntax for type uuid) at the first request with approvers or the first decision, while MySQL and SQLite store the integer silently. Nothing compares the pair at boot or at migrate time, so set both before you migrate (see Configuration).

Optional assets

Publish the config files or the exception translations only when you need to override them — the exception messages already ship in English and Slovak:

php artisan vendor:publish --tag="requests-config"
php artisan vendor:publish --tag="approvals-config"
php artisan vendor:publish --tag="requests-translations"

Next steps

  • Add GivesApprovals to the models that approve, and HasRequests to the models that submit (Model setup).
  • Create your first request with Requests::make() (Creating requests).
  • Schedule requests:expire if requests should lapse (Cancel & expire).

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.