Comments (5)
Hi @Kryptonien. Please post your migration here.
Thanks
from laravel-multitenancy.
Hey @masterix21
Here's what I have:
// migrations/landlord/2023_06_30_210521_create_landlord_tenants_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateLandlordTenantsTable extends Migration
{
public function up(): void
{
Schema::create('tenants', static function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('domain')->unique();
$table->string('database')->unique();
$table->timestamps();
});
}
}
// migrations/2022_12_07_013735_create_permission_tables.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Spatie\Permission\PermissionRegistrar;
class CreatePermissionTables extends Migration
{
public function up()
{
$tableNames = config('permission.table_names');
$columnNames = config('permission.column_names');
$teams = config('permission.teams');
if (empty($tableNames)) {
throw new Exception('Error: config/permission.php not loaded. Run [php artisan config:clear] and try again.');
}
if ($teams && empty($columnNames['team_foreign_key'] ?? null)) {
throw new Exception('Error: team_foreign_key on config/permission.php not loaded. Run [php artisan config:clear] and try again.');
}
Schema::create($tableNames['permissions'], function (Blueprint $table) {
$table->bigIncrements('id'); // permission id
$table->string('name', 125); // For MySQL 8.0 use string('name', 125);
$table->string('guard_name', 125); // For MySQL 8.0 use string('guard_name', 125);
$table->timestamps();
$table->unique(['name', 'guard_name']);
});
Schema::create($tableNames['roles'], function (Blueprint $table) use ($teams, $columnNames) {
$table->bigIncrements('id'); // role id
if ($teams || config('permission.testing')) { // permission.testing is a fix for sqlite testing
$table->unsignedBigInteger($columnNames['team_foreign_key'])->nullable();
$table->index($columnNames['team_foreign_key'], 'roles_team_foreign_key_index');
}
$table->string('display_name', 125);
$table->string('name', 125); // For MySQL 8.0 use string('name', 125);
$table->string('guard_name', 125); // For MySQL 8.0 use string('guard_name', 125);
$table->timestamps();
if ($teams || config('permission.testing')) {
$table->unique([$columnNames['team_foreign_key'], 'name', 'guard_name']);
} else {
$table->unique(['name', 'guard_name']);
}
});
Schema::create($tableNames['model_has_permissions'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) {
$table->unsignedBigInteger(PermissionRegistrar::$pivotPermission);
$table->string('model_type');
$table->unsignedBigInteger($columnNames['model_morph_key']);
$table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_model_id_model_type_index');
$table->foreign(PermissionRegistrar::$pivotPermission)
->references('id') // permission id
->on($tableNames['permissions'])
->onDelete('cascade');
if ($teams) {
$table->unsignedBigInteger($columnNames['team_foreign_key']);
$table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index');
$table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotPermission, $columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_permission_model_type_primary');
} else {
$table->primary([PermissionRegistrar::$pivotPermission, $columnNames['model_morph_key'], 'model_type'], 'model_has_permissions_permission_model_type_primary');
}
});
Schema::create($tableNames['model_has_roles'], function (Blueprint $table) use ($tableNames, $columnNames, $teams) {
$table->unsignedBigInteger(PermissionRegistrar::$pivotRole);
$table->string('model_type');
$table->unsignedBigInteger($columnNames['model_morph_key']);
$table->index([$columnNames['model_morph_key'], 'model_type'], 'model_has_roles_model_id_model_type_index');
$table->foreign(PermissionRegistrar::$pivotRole)
->references('id') // role id
->on($tableNames['roles'])
->onDelete('cascade');
if ($teams) {
$table->unsignedBigInteger($columnNames['team_foreign_key']);
$table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index');
$table->primary([$columnNames['team_foreign_key'], PermissionRegistrar::$pivotRole, $columnNames['model_morph_key'], 'model_type'], 'model_has_roles_role_model_type_primary');
} else {
$table->primary([PermissionRegistrar::$pivotRole, $columnNames['model_morph_key'], 'model_type'], 'model_has_roles_role_model_type_primary');
}
});
Schema::create($tableNames['role_has_permissions'], function (Blueprint $table) use ($tableNames) {
$table->unsignedBigInteger(PermissionRegistrar::$pivotPermission);
$table->unsignedBigInteger(PermissionRegistrar::$pivotRole);
$table->foreign(PermissionRegistrar::$pivotPermission)
->references('id') // permission id
->on($tableNames['permissions'])
->onDelete('cascade');
$table->foreign(PermissionRegistrar::$pivotRole)
->references('id') // role id
->on($tableNames['roles'])
->onDelete('cascade');
$table->primary([PermissionRegistrar::$pivotPermission, PermissionRegistrar::$pivotRole], 'role_has_permissions_permission_id_role_id_primary');
});
app('cache')
->store(config('permission.cache.store') !== 'default' ? config('permission.cache.store') : null)
->forget(config('permission.cache.key'));
}
public function down()
{
$tableNames = config('permission.table_names');
if (empty($tableNames)) {
throw new Exception('Error: config/permission.php not found and defaults could not be merged. Please publish the package configuration before proceeding, or drop the tables manually.');
}
Schema::drop($tableNames['role_has_permissions']);
Schema::drop($tableNames['model_has_roles']);
Schema::drop($tableNames['model_has_permissions']);
Schema::drop($tableNames['roles']);
Schema::drop($tableNames['permissions']);
}
}
from laravel-multitenancy.
Try with it:
<?php
use Spatie\Multitenancy\Models\Tenant;
use Spatie\Multitenancy\Tasks\SwitchTenantTask;
use Spatie\Permission\PermissionRegistrar;
class SwitchSpatiePermissionsTask implements SwitchTenantTask
{
protected ?string $originalSpatiePermissionCacheKey;
public function makeCurrent(Tenant $tenant): void
{
$this->originalSpatiePermissionCacheKey = PermissionRegistrar::$cacheKey;
$this->setup($tenant);
}
private function setup(Tenant $tenant)
{
PermissionRegistrar::$cacheKey .= '.'.$tenant->id;
}
public function forgetCurrent(): void
{
PermissionRegistrar::$cacheKey = $this->originalSpatiePermissionCacheKey;
}
}
from laravel-multitenancy.
This won't work as I am relying on PrefixCacheTask
provided by this package. The root problem comes from the fact that even after switching cache prefix, it is somehow ignored in console.
Here's a rough idea of the workflow (imo),
- From a browser
- Accessing my website (hello.example.com)
- DomainTenantFinder.php will switch to Tenant hello
- Tasks are executed, new prefix cache is set by
PrefixCacheTask.php
- spatie/laravel-permission is initialised by the Framework (set the cacheManager)
- Render the website, permissions are loaded properly, no issue here
- From a console
- Running artisan command
php artisan give:permission admin 'edit file'
- spatie/laravel-permission is initialised by the Framework (set the cacheManager)
GivePermissionsCommand.php
will switch to Tenant hello usingTenantAware.php
- Tasks are executed, new prefix cache is set by
PrefixCacheTask.php
(but laravel-permission cacheManager is not updated) handle
method is executed by the Framework
- Running artisan command
Conclusion, spatie/laravel-permission is initialised before PrefixCacheTask
is being executed while in console. Changing $cacheKey
won't fix the problem.
However, based on your suggestion, I could override PrefixCacheTask.php
and do the following
protected function setCachePrefix(string $prefix)
{
config()->set('cache.prefix', $prefix);
app('cache')->forgetDriver($this->storeName);
// This is important because the `CacheManager` will have the `$app['config']` array cached
// with old prefixes on the `cache` instance. Simply calling `forgetDriver` only removes
// the `$store` but doesn't update the `$app['config']`.
app()->forgetInstance('cache');
//This is important because the Cache Repository is using an old version of the CacheManager
app()->forgetInstance('cache.store');
// Forget the cache repository in the container
app()->forgetInstance(Repository::class);
// Force cache for Tenant.
app()->make(PermissionRegistrar::class)->initializeCache();
Cache::clearResolvedInstances();
}
This might work.
from laravel-multitenancy.
Thanks for your share.
from laravel-multitenancy.
Related Issues (20)
- Conflict with Rabbitmq package from vyuldashev HOT 1
- Scheduler : Large (longer) jobs, multiple tenants, stops.
- Tenant-Aware Job Scheduling with Horizon HOT 4
- MakeQueueTenantAwareAction seems to break active requests when Queue Connection is sync HOT 4
- base table or view not found with AWS SQS queue for job TenantAware HOT 12
- randomly receive Invalid catalog name: 1046 No database selected (Connection: mysql, SQL: insert into failed_jobs (uuid, connection, queue, payload, exception, failed_at) on queue sqs HOT 5
- Tenant Aware Queue Fails No Database Selected when running from supervisor in a multi tenant environment using AWS SQS FIFO HOT 2
- Update documentation at https://spatie.be to `v3` HOT 3
- in_array(): Argument #2 ($haystack) must be of type array, null given {"exception":"[object] (TypeError(code: 0): in_array(): Argument #2 ($haystack) must be of type array, null given at /spatie/laravel-multitenancy/src/Actions/MakeQueueTenantAwareAction.php:79) HOT 1
- Issue with the has function on different connections HOT 1
- I want to Connect to mongo DB for some tables but it is giving "Database connection [mongodb] not configured.", exception: "InvalidArgumentException",…} error
- Custom cache driver missing when switching Tenant HOT 2
- Cannot schedule jobs in Laravel 11 HOT 3
- Can't make route not tenant aware
- Erro during Laravel 11 for Notification multitenacy for multi-database
- Problem to install in Laravel 11 HOT 1
- Laravel 11: Multiple database does not switch and use tenant database HOT 2
- NeedsTenant with route model binding HOT 1
- Spatie\Multitenancy\Concerns\UsesMultitenancyConfig should be moved to ImplementsTenant? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from laravel-multitenancy.