Model setup
Approvers
Any model that should approve requests — typically your User — uses the approvals engine’s actor trait and interface:
use Illuminate\Database\Eloquent\Model;
use RoundlyConsulting\Approvals\Interfaces\GivesApprovalsInterface;
use RoundlyConsulting\Approvals\Traits\GivesApprovals;
class User extends Model implements GivesApprovalsInterface
{
use GivesApprovals;
}The actor gains the full approvals API:
$alice->approve($request, 'Looks good'); // record an approval with a reason
$alice->reject($request, 'Out of policy'); // record a rejection with a reason
$alice->cancelApproval($request); // withdraw the decision
$alice->hasApproved($request); // bool
$alice->hasRejected($request); // bool
$alice->delegateApprovalsTo($bob); // see DelegationDecisions made directly on the actor still move the request’s Status whenever the engine resolves its approval request. For the full requests event surface (ApprovalRecorded, ApprovalRevoked) and for requests with no declared approvers, decide through the Requests facade instead (Resolving requests).
Only a declared approver — or someone they delegated to — may decide, on the actor too: $mallory->approve($request) throws the engine’s UnauthorizedApprovalException and records nothing.
Authors
Add the HasRequests trait and contract to any model that submits requests. It gets a morphMany relation plus status-filtered shortcuts:
use RoundlyConsulting\Requests\Concerns\HasRequests;
use RoundlyConsulting\Requests\Contracts\HasRequests as HasRequestsContract;
class User extends Model implements HasRequestsContract
{
use HasRequests;
}
$user->requests; // morphMany relation
$user->openRequests()->get(); // status = New
$user->approvedRequests()->get();
$user->rejectedRequests()->get();The relations resolve the model configured at requests.model, so a custom subclass comes back from $user->requests.
Both on one model
The traits don’t collide, so the same model can submit and approve:
use Illuminate\Foundation\Auth\User as Authenticatable;
use RoundlyConsulting\Approvals\Interfaces\GivesApprovalsInterface;
use RoundlyConsulting\Approvals\Traits\GivesApprovals;
use RoundlyConsulting\Requests\Concerns\HasRequests;
use RoundlyConsulting\Requests\Contracts\HasRequests as HasRequestsContract;
class User extends Authenticatable implements GivesApprovalsInterface, HasRequestsContract
{
use GivesApprovals;
use HasRequests;
}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 cryptoBy 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.