Exemple practice
Această pagină este un mic „cookbook": pattern-uri compuse, luate din proiecte reale Workleto (School, Jobs, Triatlon, aplicații interne folosite aici doar ca ilustrație). Nu re-explică concepte, ci arată cum se combină. Pentru fundamente, urmează link-urile către paginile dedicate.
Upsert (find-or-create)
Un pattern frecvent: cauți după un criteriu unic, actualizezi dacă există, creezi dacă nu. Cheia este să reții dacă rândul e nou și să chemi create() sau update() corespunzător.
public static function fromCandidate(Candidate $candidate, int $parentId): self
{
$student = self::where('nin', $candidate->nin)->first();
$isNew = !$student;
if ($isNew) {
$student = new self();
}
$student->parent_id = $parentId;
$student->name = $candidate->name;
$student->nin = $candidate->nin;
if ($isNew) {
$student->enrolled_date = new \DateTimeImmutable();
$student->create();
} else {
$student->update();
}
return $student;
}Vezi Operațiuni CRUD pentru create(), update() și first().
Construire dinamică de interogări
Poți construi o interogare în pași, adăugând condiții doar când e cazul, fără să spargi lanțul fluent. Rezultatul parțial e un query care se execută abia la get()/paginate().
$jobs = JobModel::where('parent_id', null)
->with(['user', 'description'])
->orderBy('id', Order::DESC);
// Filtre opționale, adăugate condiționat
if ($filter !== 'global') {
$jobs->andWhere('namespace', Company::get('namespace'));
if (!User::isAdmin()) {
$jobs->andWhere('user_id', User::getId());
}
}
if ($filter === 'running') {
$jobs->andWhere('status', 'IN', [
JobStatus::SCHEDULED->value,
JobStatus::RUNNING->value,
]);
}
$paginationInfo = null;
$jobs = $jobs->paginate($page, $perPage, $paginationInfo);Vezi Operațiuni CRUD pentru where()/andWhere(), paginare și enum-ul Order la nivel de model.
Cheie compusă care e și cheie străină
Un câmp poate fi în același timp parte din cheia primară și cheie străină. Combini #[PrimaryKey] cu #[BelongsTo] pe aceeași proprietate:
class Contract extends Model
{
// Cheie primară compusă: school_year_id + number
#[PrimaryKey]
#[BelongsTo('school_year', SchoolYear::class, 'id')]
public int $school_year_id;
#[PrimaryKey]
public int $number;
}Pentru un rând cu cheie compusă, find() primește un array cu toate componentele: Contract::find(['school_year_id' => 3, 'number' => 42]). Vezi Relații și Operațiuni CRUD.