Get "PHP 8 in a Nuthshell" (Now with PHP 8.4)
Amit Merchant

Amit Merchant

A blog on PHP, JavaScript, and more

Using non-conventional columns in Laravel's Migrations

Migrations in Laravel are a great way to manage your database schema. From the ability to easily create and drop tables, to the ability to add and remove columns, migrations are an essential part of any Laravel application.

And though migrations covers everything related to a database schema under the sun, there might be a few things that might be missing. Like when you upgrade your application to use a new version of MySQL, chances are Laravel might not have support of the new column types.

So, for instance, imagine a scenario, where we would like to create a:

  • Table named posts
  • Containing auto-increment column id
  • Containing an integer column of display width 1 named legacy_boolean with a default value of 0
  • Containing a composite index for these two columns

The example is pretty trivial but it’s just to illustrate the point.

As of today, you would have to use database statements to add such columns like so.

new class extends Migration {
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
        });

        DB::statement('alter table `posts` add `legacy_boolean` int(1) default 0 not null');

        Schema::table('posts', function (Blueprint $table) {
            $table->index(['id', 'legacy_boolean']);
        });
    }
};

This works fine but as you might have noticed, there’s a sacrifice you have to make here. We cannot use a single table creation callback, because database statements are fired immediately and therefore cannot be used in Schema::create(<table>, <callback>).

To get around this, we now have a new method called Blueprint::rawColumn() which supports directly specifiying the column type definition used for creating a column.

So, we can rewite the above migration as follows.

new class extends Migration {
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->rawColumn('legacy_boolean', 'int(1)')->default(0);
            $table->index(['id', 'legacy_boolean']);
        });
    }
};

As you can tell, the rawColumn() method accepts the column type definition as the second argument where you can specify the column type which Laravel doesn’t support out of the box which is pretty convenient.

Learn the fundamentals of PHP 8 (including 8.1, 8.2, 8.3, and 8.4), the latest version of PHP, and how to use it today with my new book PHP 8 in a Nutshell. It's a no-fluff and easy-to-digest guide to the latest features and nitty-gritty details of PHP 8. So, if you're looking for a quick and easy way to PHP 8, this is the book for you.

Like this article?

Buy me a coffee

👋 Hi there! I'm Amit. I write articles about all things web development. You can become a sponsor on my blog to help me continue my writing journey and get your brand in front of thousands of eyes.

Comments?