Salt la conținut

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.