Files
Obsidian-Vault/Career/Others/Laravel tips.md
2025-10-25 20:11:21 +02:00

2.2 KiB

created, updated
created updated
2025-01-31 10:42 2025-07-04 07:36

Dynamic Tenancy Scoping

BelongsToRelation Trait

trait BelongsToRelation  
{  
    public static function bootBelongsToRelation(): void  
    {  
        if (static::belongsDirectlyToRelation()) {  
            static::addGlobalScope(new RelationScope());  
            return;  
        }  
  
        static::addGlobalScope(new RelationThroughScope());  
    }  
  
    public static function belongsDirectlyToRelation(): bool  
    {  
        return !static::getRelationThroughRelationship();  
    }  
  
    abstract public static function getRelationThroughRelationship(): ?string;  
  
    public function relation(): BelongsTo  
    {  
        return $this->belongsTo(Relation::class);  
    }  
}

RelationScope

  
class RelationScope implements Scope  
{  
    public function apply(Builder $builder, Model $model): void  
    {  
        if (!Bouncer::inRelationScope()) {  
            return;  
        }  
  
        $builder->where($model->qualifyColumn('relation_id'), Bouncer::getRelationId());  
  
        if (method_exists($model, 'modifyRelationScope')) {  
            $model->modifyRelationScope($builder);  
        }  
    }  
  
    public function extend(Builder $builder): void  
    {  
        $builder->macro('withoutRelationScope', function (Builder $builder) {  
            return $builder->withoutGlobalScope($this);  
        });  
  
        $builder->macro('withOutsideRelationScope', function (Builder $builder, string $relations) {  
            return $builder->with([$relations => fn($query) => $query->withoutWarehouseScope()]);  
        });  
    }  
}

RelationThroughScope

class RelationThroughScope implements Scope  
{  
    public function apply(Builder $builder, Model $model): void  
    {  
        if (!Bouncer::inRelationScope()) {  
            return;  
        }  
  
        $builder->whereHas($builder->getModel()->getRelationThroughRelationship());  
    }  
  
    public function extend(Builder $builder): void  
    {  
        $builder->macro('withoutRelationScope', function (Builder $builder) {  
            return $builder->withoutGlobalScope($this);  
        });  
    }  
}