正如标题所说,我如何知道 Laravel 中 Model 的字段是否是外键?
假设我有一个名为 show_type_id 的 FK 列和一个名为 Event 的模型,我想知道是否有一个函数给定模型类或模型表,并且指定字段如果是则返回 true,如果不是则返回 false。
...
$model = Event:class; // or Event::getTable();
$isFK = isFK('show_type_id', $model);
...
感谢@piscator,这就是有效的:
use Illuminate\Support\Facades\Schema;
function isFK(string $table, string $column): bool
{
$fkColumns = Schema::getConnection()
->getDoctrineSchemaManager()
->listTableForeignKeys($table);
$fkColumns = collect($fkColumns);
return $fkColumns->map->getColumns()->flatten()->search($column) !== FALSE;
}
试试这个,假设你的表名称是“events”:
Schema::getConnection()
->getDoctrineSchemaManager()
->listTableForeignKeys('events')
这将返回
Doctrine\DBAL\Schema\ForeignKeyConstraint
对象。
有了这些数据,你就可以编写像这样的
isFK
方法:
use Illuminate\Support\Facades\Schema;
function isFK(string $table, string $column): bool
{
$fkColumns = Schema::getConnection()
->getDoctrineSchemaManager()
->listTableForeignKeys($table);
return collect($fkColumns)->map(function ($fkColumn) {
return $fkColumn->getColumns();
})->flatten()->contains($column);
}
我创建了这个 Trait 以用于我的迁移:
<?php
namespace App\Traits;
use Illuminate\Support\Facades\Schema;
trait ChecksForeignKeys {
/**
* Check if a foreign key exists
*
* @param string $table
* @param string $column
* @param string $foreignTable
* @param string $foreignColumn
* @param string $connection
* @return boolean
*/
public function hasForegin($table, $column, $foreignTable, $foreignColumn, $connection = null) {
// Get the foreign keys for the table
$fkColumns = Schema::getConnection()
->getDoctrineSchemaManager()
->listTableForeignKeys($table);
// Check if the foreign key exists
foreach($fkColumns as $fkColumn) {
if($fkColumn->getLocalColumns()[0] == $column && $fkColumn->getForeignColumns()[0] == $foreignColumn && $fkColumn->getForeignTableName() == $foreignTable) {
return true;
}
}
return false;
}
}
Schema::table('table_name', function (Blueprint $table) {
if (Schema::hasColumn('table_name', 'column_name')) {
try {
$table->dropForeign(['column_name']);
} catch (SchemaException $e) {
// Foreign key doesn't exist, so just catch the exception and move on.
}
}
});