cycle/schema-builder
Fluent PHP schema builder for Cycle ORM. Define tables, columns, indexes and relations in code, then generate/compile database schema changes for migrations and tooling. Helps keep your domain models and database structure in sync.
Installation
composer require cycle/schema-builder
Add to composer.json under require-dev if only for migrations:
"cycle/schema-builder": "^1.0"
Basic Schema Definition
Create a schema builder class (e.g., app/Schemas/UserSchema.php):
use Cycle\Schema\Builder;
use Cycle\Schema\Table;
class UserSchema
{
public function build(Builder $builder): void
{
$builder->table('users', function (Table $table) {
$table->uuid('id')->primary();
$table->string('name')->notNull();
$table->timestamp('created_at')->defaultNow();
});
}
}
First Use Case: Migration
Register the schema in bootstrap/app.php:
$app->make(\Cycle\Schema\Builder::class)->build(new UserSchema());
Run migrations via Cycle ORM’s CLI:
php artisan cycle:migrate
Modular Schema Definitions
Split schemas by domain (e.g., UserSchema, PostSchema) and compose them in a root schema:
$builder->schema(new UserSchema())->schema(new PostSchema());
Reusable Schema Components Extract common patterns into traits or standalone builders:
trait SoftDeletes
{
public function addSoftDeletes(Table $table): void
{
$table->timestamp('deleted_at')->nullable();
}
}
Schema Versioning
Use schema classes with versioned namespaces (e.g., v2/UserSchema) and conditionally apply them:
if (app()->environment('production')) {
$builder->schema(new UserSchemaV2());
}
php artisan cycle:generate
cycle:schema:validate to check for inconsistencies between schema and database:
php artisan cycle:schema:validate
Dynamic Schema Generation Generate schemas from API specs (e.g., OpenAPI) or runtime data:
$builder->table('dynamic_'.$request->type, function (Table $table) use ($request) {
// ...
});
Schema Hooks Attach pre/post hooks to schema operations:
$builder->onBuild(function (Builder $builder) {
// Add indexes or triggers globally
});
Schema Caching
php artisan cycle:schema:clear
config/cycle.php during development:
'schema' => [
'cache' => env('APP_ENV') !== 'local',
],
Foreign Key Constraints
onUpdate('cascade') or onDelete('set null') explicitly:
$table->foreign('user_id')->references('id')->on('users')->onDelete('set null');
Case Sensitivity
$table->column('`user_id`')->unsigned();
php artisan cycle:schema:diff
config/cycle.php:
'debug' => true,
Custom Column Types
Extend Cycle\Schema\Column for database-specific types:
class JsonColumn extends Column
{
public function getType(): string
{
return 'jsonb';
}
}
Use it in schemas:
$table->column(new JsonColumn('metadata'));
Schema Events Listen to schema build events via Laravel’s event system:
SchemaBuilt::dispatch($builder);
Database-Specific Quirks
char(36) for UUIDs if not using a binary column.$builder->onBuild(function (Builder $builder) {
$builder->execute('PRAGMA foreign_keys = OFF;');
});
How can I help you explore Laravel packages today?