DEV Community

Grant
Grant

Posted on

Laravel 🔥 tip: Generating migrations easier

Generating database migrations in Laravel is already really easy to do with the php artisan make:migration. There are some nice ergonomics that aren't documented that will make it even easier.

I find myself struggling to write the name in snake case (replacing spaces with the _ character). I was thinking, wouldn't it be nice if I could just write it normally and it do that for me? It already does!

If we wrap the name of our migration in quotes, we're able to write it much quicker.

php artisan make:migration "my migration name"
Enter fullscreen mode Exit fullscreen mode

This will generate the correct name of the migration for us by automatically running the name through the Str::snake() helper. This means we could also have weird casing, and it will all be ok.

Auto table detections

If you want to generate the migration with the Schema::create() or Schema::table() scaffolding already there for you, you can pass a --create= or --table= option respectively.

php artisan make:migration "my migration name" --table=users
Enter fullscreen mode Exit fullscreen mode

However, the command also tries to guess your table name based on the name of your migration if you don't explicitly tell it a name.

The below example will automatically create a migration with the Schema::table('users'...) scaffolding.

php artisan make:migration "add column to users"
Enter fullscreen mode Exit fullscreen mode

We didn't specify the table option, but it detected the table based on how we named our migration.

public function up()
{
    Schema::table('users', function (Blueprint $table) {
        //
    });
}

public function down()
{
    Schema::table('users', function (Blueprint $table) {
        //
    });
}
Enter fullscreen mode Exit fullscreen mode

The up() and down() functions automatically included our table. Let's check out how.

In the MigrateMakeCommand command class, there's a call to TableGuesser::guess($name). In that guesser class, it's checking if our name contains a certain pattern:

const CREATE_PATTERNS = [
    '/^create_(\w+)_table$/',
    '/^create_(\w+)$/',
];

const CHANGE_PATTERNS = [
    '/_(to|from|in)_(\w+)_table$/',
    '/_(to|from|in)_(\w+)$/',
];
Enter fullscreen mode Exit fullscreen mode

What this means is that if our migration name is simply create_[table name]_table or just create_[table name] it will assume you're creating a table name whatever value [table name] is.

php artisan make:migration "create planets table"

# or

php artisan make:migration "create planets"
Enter fullscreen mode Exit fullscreen mode

Our migration will include the same scaffolding had we done the command this way:

php artisan make:migration --create=planets "create planets"
Enter fullscreen mode Exit fullscreen mode

Likewise for the table migrations, we can just include a few keywords along with the table name at the end of the migration name.

php artisan make:migration "add favorite color to users table"

# or 

php artisan make:migration "add favorite color to users"
Enter fullscreen mode Exit fullscreen mode

The migration will include the table details for us. You just need to include any one of the prepositions "to/from/in" followed by your table name at the end of your migration name and it will detect your table name for you automatically.

Here are some examples of good migration names that will automatically detect the users table for us:

  • "make name nullable in users"
  • "add favorite color to users table"
  • "remove ssn from users"

This behavior "rewards" us when we write meaningful migration names in the form of less typing... win!

Top comments (0)