creating-domain-model ยท diff
git:20260922.00e7bbe to git:20260922.7ecf42a
23 added, 13 removed. Audit A to A.
---
name: creating-domain-model
- description: Create or extend an Eloquent model that represents a Domain concept.
+ description: Create, extend, or fix Eloquent business models and their state transitions. Use when moving business rules out of controllers or Actions, or explicitly migrating a model into a DDD capability.
---
- # Creating a Domain Model
+ # Domain models
- Place Domain Eloquent models under:
+ New adopted models live in `App\Domain\<Capability>\Models`. Eloquent entities are the default; do not split persistence models from domain entities without a concrete need. Extending an existing legacy model does not authorize relocating it.
- App\Domain\<Capability>\Models
+ Put behavior on the entity that owns its rules. Mutate state in the model; let the Action persist it:
- Eloquent models may represent Domain entities directly.
+ ```php
+ public function cancel(): void
+ {
+ if ($this->status !== 'pending') {
+ throw new OrderCannotBeCancelled();
+ }
- Do not create a separate persistence model and domain entity unless there is a concrete need for that separation.
+ $this->status = 'cancelled';
+ }
+ ```
- Put business behavior on the Domain model when the behavior naturally belongs to that entity.
+ Here `OrderCannotBeCancelled` belongs to `App\Domain\Orders\Exceptions`. Use the project's existing enum/cast when applicable. No `save()`, HTTP response, `abort()`, policy invocation, or Infrastructure call belongs in this method. An Action calling it must explicitly save.
- Prefer:
+ Domain may produce or record an event describing a transition; Application coordinates dispatch. Do not add an event collector or base aggregate solely for DDD.
- $order->cancel();
+ Models may collaborate across capabilities in the same bounded context. Eloquent remains usable; repositories are not required for normal queries or persistence.
- over moving the cancellation rules into:
+ ## Preserve Laravel behavior
- CancelOrder::handle()
+ When a model move is explicitly in scope:
- The Action should orchestrate the use case; the Domain model should enforce its own business rules.
+ - Keep factories in `database/factories`. Map the model to its factory with `UseFactory` or `newFactory()` when required, and map the factory back using its `$model` property or the installed version's equivalent.
+ - Keep policies in `app/Policies`; register them with `Gate::policy()` in a service provider when discovery no longer matches. Do not attach an outer policy dependency to a Domain model.
+ - Update and verify relationships, model imports, route binding, auth configuration if relevant, and persisted polymorphic type mappings if a stored class name changes.
+ - Verify factory creation, authorization, and affected behavior. Do not migrate unrelated models.
- Do not add HTTP or presentation concerns to Domain models.
+ For the full sequence, see [order cancellation](../creating-action/references/order-cancellation.md).