-
-
Notifications
You must be signed in to change notification settings - Fork 0
1. Overview
This package is a tool that creates Laravel migration files by inspecting the application's models with the command php artisan implicit-migrations:generate
. Even after you change the model classes, you can run the command and generate a migration with the necessary update operations.
With the most basic configuration, the implicit-migrations:generate
artisan command looks at a Eloquent model and finds necessary information about the table properties such as the table name, primary key etc. Then it goes over the properties of the model and collects the name, type and default value information if provided. With the information collected, it creates a migration file and populates the up()
and down()
methods with the appropriate definitions.
For further details, the generator refers to some additional data in the model class which we call "Implications". These can be specified with either annotations or attributes on the class, its properties and methods.
Annotations in DocBlocks with the format @<implication-name>(<parameters>)
are recognized and interpreted as implications. For example, an annotation like this tells the generator that this integer property corresponds to an UNSIGNED
INT
column named product_id
in the order_items
table:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class OrderItem extends Model
{
/**
* @Column(unsigned: true)
*/
public int $product_id;
}
In turn, the generator produces a migration like this:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use App\Models\OrderItem as Source;
return new class extends Migration
{
public const TABLE_NAME = 'order_items';
public function getSource(): string
{
return Source::class;
}
public function tableUp(Blueprint $table): void
{
$table->id();
$table->integer('product_id')->unsigned();
$table->timestamps();
}
public function up(): void
{
Schema::create(static::TABLE_NAME, function (Blueprint $table) {
$this->tableUp($table);
});
}
public function down(): void
{
Schema::drop(static::TABLE_NAME);
}
};
You can find out more on other implications in the Implication Reference section.
Another way of specifying implications is using PHP attributes. The very same implications are avaliable as attributes with the same notation. This is the same model definition as above as far as the generator is concerned:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Toramanlis\ImplicitMigrations\Attributes\Column;
class OrderItem extends Model
{
#[Column(unsigned: true)]
public int $product_id;
}
The advantage of this option is that your IDE/Editor will recognize the attributes as the classes they are and provide autocompletion and descriptions. The down side is that the classes have to be referenced in the models and now they need to be existent in the production environment too.
The obvious approach to tackling this is just adding the implicit-migrations
package to the require
instead of require-dev
. The neat approach, on the other hand, is to get the attribute classes to the database/migrations/attributes
directory of the project by publishing them with the php artisan vendor:publish --tag=implication-attributes
command and add "database/attributes/composer.json"
to the composer.json
file like this:
...
"extra": {
"merge-plugin": {
"include": [
"database/attributes/composer.json"
]
}
}
...
This way, you can have the package in the require-dev
section of your composer.json
and still have the attribute classes available in production.
This tool doesn't only work for creating a table for a model. If you change your model and run implicit-migrations:generate
again, it will resolve the changes by referring to the already generated migrations (Only the generated migrations that is. See: Manual Migrations) and generate a new migration that applies the changes to the table structure.
For example if you update the above model and add another property to it:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class OrderItem extends Model
{
/**
* @Column(unsigned: true)
*/
public int $product_id;
public int $order_id;
}
After you run php artisan implicit-migrations:generate
having the initial migration above already in place, you will get another migration like this:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use App\Models\OrderItem as Source;
return new class extends Migration
{
public const TABLE_NAME = 'order_items';
public function getSource(): string
{
return Source::class;
}
public function tableUp(Blueprint $table): void
{
$table->integer('order_id');
}
public function tableDown(Blueprint $table): void
{
$table->dropColumn('order_id');
}
public function up(): void
{
Schema::table(static::TABLE_NAME, function (Blueprint $table) {
$this->tableUp($table);
});
}
public function down(): void
{
Schema::table(static::TABLE_NAME, function (Blueprint $table) {
$this->tableDown($table);
});
}
};
- Overview
- Installation
- Configuration
- Manual Migrations
-
Implication Reference
Table
Column
Binary
Char
CString
Integer
TinyInteger
SmallInteger
MedumInteger
BigInteger
Increments
TinyIncrements
SmallIncrements
MedumIncrements
CFloat
Decimal
DateTime
DateTimeTz
Time
TimeTz
Timestamp
TimestampTz
Enum
Set
Geometry
Geography
Computed
Index
Unique
Primary
Relationship
ForeignKey
PivotTable
PivotColumn
Off