LinkStory Wiki
【Laravel】migration時のエラー1
FAIL BadMethodCallException Method Illuminate\Database\MySqlConnection::getDoctrineSchemaManager does not exist. at vendor/laravel/framework/src/Illuminate/Macroable/Traits/Macroable.php:115
<原因>
getDoctrineSchemaManager() を呼んで “その外部キーがあるか” を判定しているのに、プロジェクトに doctrine/dbal が入っていない(or 対応しないバージョン)
→ DBALが必須。ただしLaravel 12 では使えない。
<解決>
DBALを使わない方法へ変更する。
(変更前の記述)
/**
* Check if a table has a foreign key constraint with a specific name.
*
* @param string $table_name
* @param string $constraint_name
* @return bool
*/
private function hasForeignKeyConstraint(string $table_name, string $constraint_name): bool
{
if (Schema::hasTable($table_name)) {
$connection = Schema::getConnection();
$schemaManager = $connection->getDoctrineSchemaManager();
$tableDetails = $schemaManager->listTableDetails($table_name);
$existingForeignKeys = $tableDetails->getForeignKeys();
foreach ($existingForeignKeys as $existingForeignKey) {
if ($existingForeignKey->getName() === $constraint_name) {
return true;
}
}
}
return false;
}
(変更後ファイル)
/**
* Check if a table has a foreign key constraint with a specific name.
*
* @param string $table_name
* @param string $constraint_name
* @return bool
*/
private function hasForeignKeyConstraint(string $tableName, string $constraintName): bool
{
if (! Schema::hasTable($tableName)) {
return false;
}
$driver = Schema::getConnection()->getDriverName();
if ($driver === 'mysql') {
$row = DB::selectOne(
"SELECT CONSTRAINT_NAME
FROM information_schema.TABLE_CONSTRAINTS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = ?
AND CONSTRAINT_NAME = ?
AND CONSTRAINT_TYPE = 'FOREIGN KEY'",
[$tableName, $constraintName]
);
return $row !== null;
}
if ($driver === 'pgsql') {
// (PostgreSQLの例:必要なら)
$row = DB::selectOne(
"SELECT c.conname
FROM pg_constraint c
JOIN pg_class t ON c.conrelid = t.oid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE c.contype = 'f'
AND t.relname = ?
AND c.conname = ?
AND n.nspname = ANY (current_schemas(false))",
[$tableName, $constraintName]
);
return $row !== null;
}
// 他ドライバは必要に応じて追加
return false;
}