86 lines
2.2 KiB
Markdown
86 lines
2.2 KiB
Markdown
---
|
|
created: 2025-01-31 10:42
|
|
updated: 2025-07-04 07:36
|
|
---
|
|
### Dynamic Tenancy Scoping
|
|
|
|
BelongsToRelation Trait
|
|
```php
|
|
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
|
|
```php
|
|
|
|
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
|
|
```php
|
|
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);
|
|
});
|
|
}
|
|
}
|
|
``` |