ADR: ORM Models
Status
To Validate
Context
The models are based on non standard functionality, a very old eloquent version and custom behaviour.
We want to standardise models and database to simplify functionality and structure. We also want to limit how much eloquent magic we use to limit divergence and simplify changes.
Decision
General Rules
- Models MUST extend
AppModelor a child
Relationships
- Foreign keys SHOULD be represented with relationships on model. This makes it easy to navigate
- Use adequate eloquent relationships
HasOne,HasMany,BelongsTo, etc.
Model Integrity
- A model MUST take care of its integrity. That includes initialisation and domain changes
- Model intricacies SHOULD NOT be exposed, it SHOULD only expose state changes that make sense on the domain
- Do not expose DB field getters and setters (it's not a DTO) but model domain changes (that might or might not be translatable to singular DB fields)
- Example:
->flag($member, $reason)instead of->setFlaggedBy($member); ->setFlaggedReason($reason); ->setFlaggedTimestamp($now)
Related Models
- A model SHOULD take care of related models that define its state
- These are part of the internal intricacies that don't need to be exposed unnecessarily
- Example: Related models used to store flagged status or state history
- Internal models SHOULD be on an
Internalnamed namespace - Internal models MUST use
App\Domain\Model\Internalannotation mentioning what classes implement them (and are allowed to use them) - Example:
#[Internal(CommentModel::class, CommentableTrait::class)]
Model Responsibilities
- A model MUST NOT operate on multiple instances of itself, use Repositories
- A model MUST NOT return
Illuminate\Support\Collectionor otherArrayAccessclasses, usearray
Timestamps
- If model uses timestamps, it MUST use eloquent ones
created_at,updated_at - MUST be of type
DATETIME, not nullable and default tocurrent_timestamp() - SHOULD NOT be set manually
- SHOULD use
ModelTimestampsTrait
Soft Deletes
- If model can be soft deleted, it MUST use eloquent system with
deleted_at - SHOULD implement
StateChangeable - SHOULD use
StateChangeableTraitandHasDeletedTrait - If model cannot be soft deleted but its children can, it MUST ensure propagation of soft deletes and restores
- SHOULD implement
SoftDeletable - SHOULD use
SoftDeleteTrait
Consequences
Models are standardised and successfully implement SOLID principles while using Eloquent functionalities.
Impact
High
Driver
@Eudald Rossell Vivo
Contributors
[Team]
Accepted Date
[Pending validation]