If you have an existing model with a uuid primary key, and you'd like to change it to an auto-incrementing integer, then this post will get you most of the way there. This post isn't complete, it doesn't mention how to deal with foreign keys and morphables. You're on you're own for that one.
class ChangeUserPrimaryKeyType extends Migration
{
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->dropPrimary('id');
$table->renameColumn('id', 'uuid');
$table->unique('uuid');
});
Schema::table('users', function (Blueprint $table) {
$table->unsignedBigInteger('id')->after('uuid')->nullable();
});
// If you're using soft-deletes, add `withTrashed()`
foreach (User::orderBy('created_at')->pluck('uuid') as $i => $uuid) {
User::where('uuid', $uuid)->update(['id' => $i + 1]);
}
Schema::table('users', function (Blueprint $table) {
$table->unsignedBigInteger('id')->nullable(false)->change();
$table->primary('id');
});
Schema::table('users', function (Blueprint $table) {
$table->unsignedBigInteger('id', autoIncrement: true)->change();
});
// Optional: move the uuid column after the new id column
DB::statement('ALTER TABLE users MODIFY COLUMN uuid char(36) AFTER id');
}
}
After changing the primary key, you can remove these attributes from your model:
class User extends Model
{
protected $keyType = 'string';
public $incrementing = false;
}
Don't forget to update any route model bindings if you still want to use the uuid:
// Before: this used the uuid
Route::get('/profile/{user}', [UsersController::class, 'show']);
// After: if you still want to use the uuid
Route::get('/profile/{user:uuid}', [UsersController::class, 'show']);
Level up your Laravel deployments
If you aren't happy with your current deployment strategy for your Laravel apps, check out my premium deployment script.
Deploy with GitHub Actions
Deploy with GitLab CI/CD