Laravel
Migration
Rename Column
Database Schema
Web Development

How can I rename column in laravel using migration?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Renaming a database column in Laravel is a common task that arises as your application evolves -- maybe you named a column user_name and later realized the convention should be username, or a business requirement changed and price needs to become unit_price. Laravel migrations give you a version-controlled, reversible way to make this change safely. Understanding the full process matters because a botched column rename on a production database can break every query that references the old name.

Prerequisites: The doctrine/dbal Package

Before you can rename any column, Laravel requires the doctrine/dbal package. This is because Laravel's schema builder delegates column introspection and modification to Doctrine's database abstraction layer. Without it, calling renameColumn() throws a runtime exception.

bash
composer require doctrine/dbal

Starting with Laravel 11, the framework includes its own schema management for column operations on SQLite, MySQL, and PostgreSQL, so doctrine/dbal may no longer be required depending on your database driver. For Laravel 10 and earlier, this package is mandatory.

Creating the Migration

Use Artisan to generate a migration file with a descriptive name. The name should clearly communicate what the migration does, since you and your teammates will read these names in directory listings and migration status output.

bash
php artisan make:migration rename_user_name_to_username_in_users_table

This creates a timestamped file in the database/migrations directory. Open it and define the column rename in the up() method:

php
1<?php
2
3use Illuminate\Database\Migrations\Migration;
4use Illuminate\Database\Schema\Blueprint;
5use Illuminate\Support\Facades\Schema;
6
7return new class extends Migration
8{
9    public function up(): void
10    {
11        Schema::table('users', function (Blueprint $table) {
12            $table->renameColumn('user_name', 'username');
13        });
14    }
15
16    public function down(): void
17    {
18        Schema::table('users', function (Blueprint $table) {
19            $table->renameColumn('username', 'user_name');
20        });
21    }
22};

The up() method applies the rename going forward. The down() method reverses it, restoring the original column name when you roll back. Always write both methods -- a migration without a down() method cannot be safely rolled back during development or deployment failures.

Run the migration:

bash
php artisan migrate

Renaming Multiple Columns

You can rename several columns in a single migration. Each renameColumn() call handles one column, and you can chain them within the same Schema::table closure.

php
1public function up(): void
2{
3    Schema::table('orders', function (Blueprint $table) {
4        $table->renameColumn('price', 'unit_price');
5        $table->renameColumn('qty', 'quantity');
6        $table->renameColumn('desc', 'description');
7    });
8}
9
10public function down(): void
11{
12    Schema::table('orders', function (Blueprint $table) {
13        $table->renameColumn('unit_price', 'price');
14        $table->renameColumn('quantity', 'qty');
15        $table->renameColumn('description', 'desc');
16    });
17}

Keep related renames in the same migration so they are applied and rolled back as a single atomic unit. If renaming columns across different tables, you can either use separate Schema::table blocks in one migration or create separate migrations -- the choice depends on whether the renames are logically connected.

Handling Indexes During a Rename

When you rename a column that has an index, the behavior depends on your database driver. MySQL automatically renames the index to match the new column name in most cases. PostgreSQL and SQLite may leave the old index name intact, which can cause confusion.

If you need to explicitly manage indexes, drop the old index and create a new one in the same migration:

php
1public function up(): void
2{
3    Schema::table('users', function (Blueprint $table) {
4        // Drop the old index first
5        $table->dropIndex('users_user_name_index');
6
7        // Rename the column
8        $table->renameColumn('user_name', 'username');
9
10        // Create a new index with the correct name
11        $table->index('username');
12    });
13}

The index name in Laravel follows the convention {table}_{column}_{type} -- for example, users_username_index for a standard index or users_email_unique for a unique constraint.

Handling Foreign Keys During a Rename

Foreign key constraints are the most dangerous part of a column rename. If a column is referenced by a foreign key (either as the parent or child), you must drop the constraint before renaming and recreate it afterward.

php
1public function up(): void
2{
3    Schema::table('posts', function (Blueprint $table) {
4        // Drop the foreign key constraint
5        $table->dropForeign('posts_user_name_foreign');
6
7        // Rename the column
8        $table->renameColumn('user_name', 'username');
9
10        // Recreate the foreign key
11        $table->foreign('username')
12              ->references('username')
13              ->on('users')
14              ->onDelete('cascade');
15    });
16}
17
18public function down(): void
19{
20    Schema::table('posts', function (Blueprint $table) {
21        $table->dropForeign('posts_username_foreign');
22        $table->renameColumn('username', 'user_name');
23        $table->foreign('user_name')
24              ->references('user_name')
25              ->on('users')
26              ->onDelete('cascade');
27    });
28}

If you are unsure of the exact foreign key name, run php artisan migrate:status or check your database directly. Laravel names foreign keys as {table}_{column}_foreign by default.

Rolling Back Migrations

Laravel tracks which migrations have been applied in the migrations table. To undo the most recent batch of migrations:

bash
php artisan migrate:rollback

To roll back a specific number of steps:

bash
php artisan migrate:rollback --step=1

This is why the down() method is critical. If you deployed a migration that renamed user_name to username and something broke, rolling back instantly restores the original column name without manual SQL.

Common Pitfalls

  • Forgetting to install doctrine/dbal: On Laravel 10 and earlier, renameColumn() throws a RuntimeException. Install the package before writing your migration.
  • Not writing the down() method: Skipping down() means you cannot roll back the migration. During development this is frustrating; in production it can be catastrophic if you need to revert a bad deployment.
  • Renaming a column referenced by application code: The migration only changes the database. You must also update every Eloquent model, query, validation rule, and API response that references the old column name.
  • Ignoring foreign key constraints: Renaming a column that participates in a foreign key without dropping the constraint first causes a database error. Always check for foreign keys before renaming.
  • Combining rename with type change in one call: Laravel does not support renaming and changing a column type in a single operation. Split them into two separate calls within the same migration.

Summary

  • Use $table->renameColumn('old', 'new') inside a Schema::table closure to rename a column in Laravel.
  • Install doctrine/dbal via Composer for Laravel 10 and earlier -- it is required for column modification operations.
  • Always write both up() and down() methods so migrations are fully reversible.
  • Drop and recreate indexes and foreign keys explicitly when renaming columns they reference.
  • Rename multiple columns in a single migration when the changes are logically related.
  • After running the migration, update all application code (models, queries, validation rules) that references the old column name.

Course illustration
Course illustration

All Rights Reserved.