Laravel 🔥 tip: Generating migrations easier
Tags: laravel
Published: 2021-10-15 01:31:15

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"
```

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
```

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"
```

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

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

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

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:

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

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

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"
```

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

```
php artisan make:migration --create=planets "create planets"
```

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"
```

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!