Skip to content

Instantly share code, notes, and snippets.

@kkbt
Created January 1, 2022 05:48
Show Gist options
  • Save kkbt/184b489e4e89cfc9587bd3d3962800c6 to your computer and use it in GitHub Desktop.
Save kkbt/184b489e4e89cfc9587bd3d3962800c6 to your computer and use it in GitHub Desktop.
Script to reproduce the problem in Laravel / tenancy ("There is no active transaction")
#!/bin/zsh
set -e # exit on error
# zsh running an a Mac
new_server_dir='server_mwe'
# Create fresh Laravel installation
rm -rf $new_server_dir
laravel new $new_server_dir --jet --teams --stack=inertia
cd $new_server_dir
# Create fresh database
echo "drop database if exists $new_server_dir; create database if not exists $new_server_dir;" | mysql
echo "drop database if exists ${new_server_dir}_client_1;" | mysql
# Make Laravel app multi-tenant
composer require stancl/tenancy
php artisan tenancy:install
php artisan migrate
# Insert "App\Providers\TenancyServiceProvider::class," after "App\Providers\RouteServiceProvider::class,",
# following the instructions at https://laravel-news.com/multi-tenant (January 1, 2022)
app=config/app.php
line_no=`grep -n RouteServiceProvider $app | sed -E 's/:.*//'`
sed -i '' $line_no'a\'$'\n App\\\\Providers\\\\TenancyServiceProvider::class,\n' $app
# Add new class 'Tenant'
tenant=app/Models/Tenant.php
cat > $tenant << 'EOF'
<?php
namespace App\Models;
use Stancl\Tenancy\Database\Concerns\CentralConnection;
use Stancl\Tenancy\Database\Models\Tenant as BaseTenant;
use Stancl\Tenancy\Contracts\TenantWithDatabase;
use Stancl\Tenancy\Database\Concerns\HasDatabase;
class Tenant extends BaseTenant implements TenantWithDatabase
{
use CentralConnection;
use HasDatabase;
public static function generateDatabaseName(string $client_id): string
{
return env('DB_DATABASE') . '_client_' . $client_id;
}
}
EOF
# Edit EventServiceProvider.php: Create tenant when creating a team
provider=app/Providers/EventServiceProvider.php
# Add use statement
sed -i '' 5'a\'$'\nuse App\\\\Models\\\\Tenant;\n' $provider
# Delete last two lines
sed -i '' '$d' $provider
sed -i '' '$d' $provider
# Add new code at end of file (update function boot)
cat >> $provider << 'EOF'
// Listen to Team creation: create database
Event::listen('eloquent.created: App\Models\Team', function ($model) {
$client_id = $model->id;
$db_name = Tenant::generateDatabaseName($client_id);
$tenant = Tenant::create([
'id' => $client_id,
'tenancy_db_name' => $db_name,
]);
tenancy()->initialize($tenant);
});
}
}
EOF
# Start PHP server
php artisan serve
# Then open http://127.0.0.1:8000/register and register a new user
# Result:
#
# PDOException
# There is no active transaction
# http://127.0.0.1:8000/register
# PDO::rollBack
# vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php:279
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment