Closed torkiljohnsen closed 7 years ago
I'd really be interested in this, or knowing if it can be achieved already!
Since it's a pivot table the data would always be accessed through an already scoped model, so there would be no need to put tenant_id
on the pivot table directly, or am I missing something?
The features model would not be scoped, the pivot table is what defines the scope.
I would have three tables in this example:
features
: A list of all available features for my SaaS that tenants can activate/deactivate.tenant_features
: A pivot connecting the features with the tenants, effectively creating a list of which tenants have activated which features. Holds FKs tenant_id
and feature_id
.tenants
: The tenants table.Getting all features for a tenant would look something like this:
$features = Features::whereHas('tenant', function ($query) use ($tenantId) {
$query->where('id', $tenantId);
})->get();
Ideally I would not want to be querying tenancy manually like this, it should work automatically.
One option which could work, would be to att a model for, and access features though, the pivot table?
This might work(I didn't test it). In your Feature class, add
public static function bootBelongsToTenantThroughPivot() {
static::addGlobalScope('tenant', function (Builder $builder) {
$builder->join('tenant_features', 'tenant_features.feature_id', '=', 'features.id')->select('features.*')->where('tenant_id', \Auth::user()->tenant_id);
});
}
It basically use the same idea(check src/BelongsToTenants.php src/TenantManager.php) as Landlord to insert tenant_id filter for every query. Then you can call
Features::get()
to get features for logged in user/tenant.
That isn't what this package is for. This package is for preventing data that belongs to Tenant A form leaking into queries run for Tenant B.
What you're trying to do is just a basic many-to-many anyway. You don't need this package, just do this:
class Tenant extends Model
{
public function features() {
return $this->belongsToMany(Feature::class);
}
}
and then:
$tenant = Tenant::find(1);
$tenant->features();
Not sure why I am having this problem too. My pivot table does have the trait on it. But it wasn't applying the tenant scope like the rest of my tables.
I should add that I'm doing something unconventional, I do not use the primary key (id) to make my joins. And as such my "keys" are not unique in the table, they are only unique when combined with the the tenant_id so you could say I use composite primary keys.
I was able to fix my problem by doing this
public function posts()
{
return $this->belongsToMany('Post', 'post_user', 'user_id', 'post_id', 'another_id', 'another_id')
->where('post_user.tenant_id', \Landlord::getTenants()->first());
}
Could it be nice to also have a trait that supports many-to-many relation between tenant and another resource?
For instance if a have a table of
features
and each tenant can activate/deactivate that feature? Pivot table would holdfeature_id
andtenant_id
for instance.Would be nice when getting a list of
features
that these are automatically scoped by tenant by a trait, sayBelongsToManyTenants
perhaps?… or is this better solved in some other way I have not thought of?