Я использую многопользовательское приложение Laravel 10 с паспортом 11 hyn. Это устаревшее приложение, которому уже несколько лет, и оно работало очень хорошо, пока я не обновил свой Laravel с 9 до 10 и паспорт с 10 до 11. Когда я пытаюсь создать аренду, все работает до тех пор, пока "$company = Tenant: :create($request);" который также работает довольно хорошо до определенного момента. Он создает запись в таблицах tenancy.hostnames и tenancy.websites соответственно, а также создает пользовательскую базу данных для новой аренды. Однако он пытается воссоздать все системные таблицы, находящиеся в базе данных арендатора. Эти файлы миграции используются всем приложением и расположены в папке миграции, а остальные, составляющие базу данных каждой тенденции, находятся в папке миграции/тенанта. Я действительно не понимаю, почему создание новой аренды пытается воссоздать таблицы в базе данных арендаторов, которая, очевидно, уже существует. Я получаю эту ошибку, когда это происходит
SQLSTATE[42S01]: базовая таблица или представление уже существует: 1050 Таблица «веб-сайты» уже существует (Соединение: система, SQL: создать таблицу
websites(idbigint unsigned not null первичный ключ auto_increment,uuidvarchar(191) не равно нулю,created_atметка времени нуль) ,updated_atметка времени ноль,deleted_atметка времени ноль) набор символов по умолчанию utf8mb4 сортировка 'utf8mb4_unicode_ci')
это моя функция регистрации
public function register(Request $request)
{
$facility_name = Hostname::where('tenant_facility_name', $request->tenant_facility_name)->first();
$checkEmail = Hostname::where('email', $request->email)-`>`first();
$fqdn = Hostname::where('subdomain', $request->fqdn)->first();
if ($facility_name){
return response(['message' => 'A facility with this name already exist'], 409);
}
if ($checkEmail) {
return response(['message' => 'A facility with this email already exist'], 409);
}
if ($fqdn) {
return response(['message' => 'A facility with this name already exist'], 409);
}
// Validate the incoming request
$this->validator($request->all())->validate();
try {
// create Tenant Account
$company = Tenant::create($request);
} catch(\Exception $e) {
return response($e->getMessage(), 405);
}
event(new Registered($user = $this->create($request->all())));
// set trial period for new account without actual subscription for 30 days
// $host = HostnameModel::where('fqdn', $company->hostname->fqdn)->first();
// $host->trial_ends_at = now()->addDays(30);
// $host->save();
$this->createTrialPeriod($request->email);
// Function to send email
$name = $request->othernames . ' ' . $request->surname;
$email = $request->email;
$facilityName = $request->tenant_facility_name;
// Send email to new account admin
try {
Mail::to($email)->send(new TenantAccountCreation($name, $email, $facilityName));
} catch(\Exception $e) {
// sending 200 so that the registration continues without queing email to new account user
return response($e->getMessage(), 200);
}
return response()->json(['message' => 'Account Has Been Created Successfully'], 200);
}
и это мой файл Tenant.php
<?php
namespace App\Models\General;
use Illuminate\Support\Facades\Artisan;
use Hyn\Tenancy\Environment;
use Hyn\Tenancy\Models\Hostname;
use Hyn\Tenancy\Models\Website;
use Illuminate\Support\Str;
use Hyn\Tenancy\Contracts\Repositories\HostnameRepository;
use Hyn\Tenancy\Contracts\Repositories\WebsiteRepository;
class Tenant
{
public function __construct(Website $website = null, Hostname $hostname = null)
{
$this->website = $website ?? $sub->website;
$this->hostname = $hostname ?? $sub->websites->hostnames->first();
}
public function delete()
{
app(HostnameRepository::class)->delete($this->hostname, true);
app(WebsiteRepository::class)->delete($this->website, true);
}
public static function create($request): Tenant
{
// Create New Website
$website = new Website;
// Attached the fqdn to a random string of 5
$website->uuid = $request->fqdn.'_'.Str::random(5);
app(WebsiteRepository::class)->create($website);
// associate the website with a hostname
$hostname = new Hostname;
$hostname->subdomain = $request->fqdn;
$hostname->email = $request->email;
$hostname->currency = $request->currency;
// Add the facility name to hostname table
$hostname->tenant_facility_name = $request->tenant_facility_name;
// merge
// $request->merge(['fqdn' => $request->fqdn . '.' . env('APP_URL_BASE')]);
$fqdn = $request->fqdn . '.' .config('services.environment');
$hostname->fqdn = $fqdn;
// $hostname->fqdn = $request->fqdn;
app(HostnameRepository::class)->attach($hostname, $website);
// make hostname current
app(Environment::class)->tenant($website);
Artisan::call('passport:install');
return new Tenant($website, $hostname);
}
public static function tenantExists($name)
{
return Hostname::where('fqdn', $name)->exists();
}
}
и это мой файл data.php
<?php
use Illuminate\Support\Str;
return [
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => env('DB_CONNECTION', 'mysql'),
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => [
'system' => [
'driver' => 'mysql',
'host' => env('TENANCY_HOST', '127.0.0.1'),
'port' => env('TENANCY_PORT', '3306'),
'database' => env('TENANCY_DATABASE', 'tenancy'),
'username' => env('TENANCY_USERNAME', 'User1'),
'password' => env('TENANCY_PASSWORD', 'mypassword'),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DATABASE_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
'pgsql' => [
'driver' => 'pgsql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '5432'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
'schema' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '1433'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'prefix_indexes' => true,
],
],
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
'migrations' => 'migrations',
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer body of commands than a typical key-value system
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'client' => env('REDIS_CLIENT', 'predis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'predis'),
'prefix' => Str::slug(env('APP_NAME', 'laravel'), '_').'_database_',
],
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
],
];
обновление функции создания в моем Tenant.php до:
public static function create($request): Tenant
{
try {
// Create New Website
\Log::info('creating new website info');
$website = new Website;
// Attached the fqdn to a random string of 5
$website->uuid = $request->fqdn . '_' . Str::random(5);
app(WebsiteRepository::class)->create($website);
\Log::info('website created');
// Associate the website with a hostname
$hostname = new Hostname;
$hostname->subdomain = $request->fqdn;
$hostname->email = $request->email;
$hostname->currency = $request->currency;
$hostname->tenant_facility_name = $request->tenant_facility_name;
$fqdn = $request->fqdn . '.' . config('services.environment');
$hostname->fqdn = $fqdn;
app(HostnameRepository::class)->attach($hostname, $website);
\Log::info('creating new hostname');
// Make hostname current
app(Environment::class)->tenant($website);
\Log::info('make tenancy current');
// Run Passport install
\Log::info('starting passport install');
Artisan::call('passport:install');
\Log::info('passport installed');
return new Tenant($website, $hostname);
} catch (\Exception $e) {
\Log::error('Error creating tenant: ' . $e->getMessage());
throw $e;
}
}
это то, что записывается в файл журнала laravel
[2024-06-21 00:16:01] local.INFO: создание новой информации о веб-сайте [2024-06-21 00:17:15] local.INFO: сайт создан [2024-06-21 00:17:15] local.INFO: создание нового имени хоста [2024-06-21 00:17:15] local.INFO: сделать аренду текущей [2024-06-21 00:17:15] local.INFO: начинаем установку паспорта [2024-06-21 00:17:16] local.ERROR: Ошибка создания клиента: SQLSTATE[42S01]: Базовая таблица или представление уже существует: 1050 Таблица «Веб-сайты» уже существует (Соединение: система, SQL: создать таблицу веб-сайтов)
что ясно доказывает, что линия
Artisan::call('passport:install')
несет ответственность за ошибку.
Вопрос: Почему это так?
Artisan::call('passport:install')
команда пытается снова запустить все файлы миграции в приложении?






Мне удалось решить свои проблемы после повторной переустановки laravel/passport.