cline/variable-keys
Laravel Blueprint macros for variable primary key types, matching foreign keys, and polymorphic morph types. Easily switch between id/uuid/ulid (and more) via enums/config to keep migrations consistent across models and relationships.
composer require cline/variable-keys
config/database.php:
'primary_key_type' => env('DB_PRIMARY_KEY_TYPE', 'uuid'),
use Cline\VariableKeys\Enums\PrimaryKeyType;
Schema::create('users', function (Blueprint $table) {
$table->variablePrimaryKey(PrimaryKeyType::UUID);
$table->string('name');
$table->timestamps();
});
id() to UUIDsReplace all ->id() calls with ->variablePrimaryKey(PrimaryKeyType::UUID) in new migrations. For existing tables, add a new UUID column and backfill it.
config/database.php or .env:
DB_PRIMARY_KEY_TYPE=uuid
id() with variablePrimaryKey():
// Before
$table->id();
// After
$table->variablePrimaryKey(PrimaryKeyType::UUID);
variableForeignKey():
$table->variableForeignKey('user_id', PrimaryKeyType::UUID)
->constrained()
->cascadeOnDelete();
AppServiceProvider:
Model::morphMap([
'user' => User::class,
// Other models with variable keys
]);
getKey(), getKeyType(), and incrementPrimaryKey() methods. No additional model overrides are needed for basic usage.PrimaryKeyType enum or override getIncrementing() in your models:
class User extends Model
{
public function getIncrementing(): bool
{
return false; // For UUIDs/ULIDs
}
}
AppServiceProvider:
MorphType::configure([
'user' => MorphType::UUID,
'post' => MorphType::UUID,
]);
Schema::create('comments', function (Blueprint $table) {
$table->variablePrimaryKey(PrimaryKeyType::UUID);
$table->morphs('commentable', MorphType::UUID);
$table->timestamps();
});
config/database.php:
'key_types' => [
'primary' => 'uuid',
'foreign' => 'uuid',
'morph' => 'uuid',
],
$table->variablePrimaryKey(PrimaryKeyType::ULID);
Schema::table('posts', function (Blueprint $table) {
$table->dropForeign(['user_id']);
});
morphMap and MorphType configurations match across all polymorphic tables. Mismatches can cause ModelNotFoundException errors.CHAR(36) columns, not BINARY(16). Configure PrimaryKeyType::UUID to use string in MySQL environments.INTEGER as a fallback if UUIDs are required.$table->variablePrimaryKey(PrimaryKeyType::ULID);
$table->variablePrimaryKey(PrimaryKeyType::UUID); // Generates `uuid` column in PostgreSQL
dd($model->getKeyType(), $model->getKey());
Schema::hasTable() and Schema::hasColumn() to verify table/column existence before adding constraints:
if (Schema::hasTable('users') && Schema::hasColumn('users', 'id')) {
$table->variableForeignKey('user_id', PrimaryKeyType::UUID)->constrained();
}
PrimaryKeyType enum to support custom key types (e.g., CUSTOM_STRING):
namespace App\Enums;
use Cline\VariableKeys\Enums\PrimaryKeyType;
class AppPrimaryKeyType extends PrimaryKeyType
{
case CUSTOM_STRING = 'custom_string';
}
AppServiceProvider:
use Cline\VariableKeys\BlueprintExtensions;
BlueprintExtensions::macro('customPrimaryKey', function (Blueprint $table) {
$table->variablePrimaryKey(PrimaryKeyType::ULID);
});
MorphType for custom polymorphic key handling:
MorphType::extend('custom_morph', function () {
return 'custom_morph_key';
});
$table->variableForeignKey('user_id', PrimaryKeyType::UUID)
->constrained()
->index();
$keys = Str::uuid()->toString();
DB::table('users')->insert([['id' => $keys, 'name' => 'Test']]);
How can I help you explore Laravel packages today?