Fluent Migrations¶
Migraw's fluent API keeps common schema operations concise while keeping SQL definitions visible.
Set fluent as the default generated template:
Then create migrations normally:
Create a table¶
<?php
use Eril\Migraw\Migration;
use Eril\Migraw\Sql\SqlStatement;
return new class extends Migration
{
public function up(): SqlStatement
{
return $this->create('users')
->id()
->column('name VARCHAR(255) NOT NULL')
->column('email VARCHAR(180) NOT NULL')
->unique('uq_users_email', 'email')
->timestamps();
}
public function down(): SqlStatement
{
return $this->drop('users')->ifExists();
}
};
CreateTable methods¶
| Method | Purpose |
|---|---|
ifNotExists() |
Adds IF NOT EXISTS |
id($definition = 'id') |
Adds a conventional or custom primary-key definition |
column($definition) |
Adds a SQL column definition |
timestamps() |
Adds created_at and updated_at |
softDeletes($name = 'deleted_at') |
Adds a nullable soft-delete timestamp |
primary($columns, $name = null) |
Adds a primary-key constraint |
unique($name, $columns) |
Adds a unique constraint |
index($name, $columns) |
Adds an index |
foreign(...) |
Adds a foreign key |
constraint($definition) |
Adds a table-level constraint |
raw($definition) |
Adds a raw table definition |
id()¶
Default:
Custom column name:
UUID shorthand:
Custom SQL definition:
Migraw compiles supported shorthand according to the active database driver.
Columns¶
Column definitions are SQL fragments:
$this->create('products')
->id()
->column('name VARCHAR(255) NOT NULL')
->column('price DECIMAL(10,2) NOT NULL DEFAULT 0')
->column('active TINYINT(1) NOT NULL DEFAULT 1');
Timestamps¶
Adds conventional created_at and updated_at columns using driver-aware SQL.
Soft deletes¶
Custom name:
Primary keys¶
Single column:
Composite primary key:
Named constraint:
Unique constraints¶
Composite:
Indexes¶
Composite:
Foreign keys¶
Basic:
Custom referenced column:
Named constraint with actions:
->foreign(
columns: 'user_id',
referencesTable: 'users',
referencesColumns: 'id',
name: 'fk_posts_user',
onDelete: 'CASCADE',
onUpdate: 'CASCADE'
)
Composite foreign key:
->foreign(
['tenant_id', 'user_id'],
'tenant_users',
['tenant_id', 'user_id'],
'fk_orders_tenant_user'
)
Custom constraints¶
Raw table definition¶
Use raw() inside a fluent table builder for database-specific definitions:
$this->create('articles')
->id()
->column('title VARCHAR(255) NOT NULL')
->raw('FULLTEXT INDEX ft_articles_title (title)');
Alter a table¶
public function up(): SqlStatement
{
return $this->alter('users')
->add('phone VARCHAR(50) NULL')
->add('active TINYINT(1) NOT NULL DEFAULT 1');
}
column() and add() both add a column:
AlterTable methods¶
| Method | Purpose |
|---|---|
column($definition) |
Add a column |
add($definition) |
Alias-style helper for adding a column |
modify($definition) |
Modify an existing column |
renameColumn($from, $to) |
Rename a column |
dropColumn($name) |
Drop a column |
index($name, $columns) |
Add an index |
unique($name, $columns) |
Add a unique constraint |
foreign(...) |
Add a foreign key |
dropIndex($name) |
Drop an index |
dropForeign($name) |
Drop a foreign-key constraint |
raw($operation) |
Add a raw ALTER TABLE operation |
Modify a column¶
Rename a column¶
Rollback:
Drop a column¶
Add an index¶
Composite:
Add a unique constraint¶
Add a foreign key¶
$this->alter('posts')
->foreign(
columns: 'user_id',
referencesTable: 'users',
referencesColumns: 'id',
name: 'fk_posts_user',
onDelete: 'CASCADE'
);
Drop indexes and foreign keys¶
Raw alter operation¶
Drop a table¶
Safer rollback-style usage:
Rename a table¶
Rollback:
Multiple fluent statements¶
Return an array:
public function up(): array
{
return [
$this->create('roles')
->id()
->column('name VARCHAR(100) NOT NULL UNIQUE'),
$this->create('users')
->id()
->column('role_id INT NOT NULL')
->column('name VARCHAR(255) NOT NULL')
->foreign('role_id', 'roles'),
];
}
Rollback in reverse dependency order:
public function down(): array
{
return [
$this->drop('users')->ifExists(),
$this->drop('roles')->ifExists(),
];
}
Mix fluent and raw¶
You can mix both styles:
public function up(): array
{
return [
$this->alter('users')
->add('search_name VARCHAR(255) NULL'),
$this->raw(<<<'SQL'
CREATE INDEX idx_users_search_name
ON users (search_name);
SQL),
];
}
Use fluent helpers for supported common operations and raw SQL when the database-specific statement is clearer.