2.2 KiB
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);
});
}
}