'array', ]; protected static function booted(): void { static::deleting(function (GuidePage $page) { // CASCADE on from_page_id is handled by FK, but incoming edges need cleanup GuidePageEdge::where('to_page_id', $page->id)->delete(); }); } public function getUriAttribute(): string { return route('guides.pages.show', $this->id); } public function guide() { return $this->belongsTo(Guide::class); } public function outgoingEdges() { return $this->hasMany(GuidePageEdge::class, 'from_page_id')->orderBy('sort'); } public function incomingEdges() { return $this->hasMany(GuidePageEdge::class, 'to_page_id'); } public function nextPages() { return $this->belongsToMany(self::class, 'guide_page_edges', 'from_page_id', 'to_page_id') ->withPivot('label', 'sort') ->orderByPivot('sort'); } public function previousPages() { return $this->belongsToMany(self::class, 'guide_page_edges', 'to_page_id', 'from_page_id') ->withPivot('label', 'sort'); } public function isEntry(): bool { return !$this->incomingEdges()->exists(); } }