Framework: use macroable functionality on schema builder

Created on 29 Feb 2016  路  4Comments  路  Source: laravel/framework

i think its a little more involved than just adding the macroable trait, but it would be great if we could create macros for migration schemas.

say for example your working on a schema that has a "tenant_id" column (im not going to get into the multi tenant debate here, im aware thats a complicated issue).

it would be great if we could do this:

Blueprint::macro('tenantable', function(Blueprint $table){
    $table->integer('tenant_id')->unsigned();
    $table->foreign('tenant_id')
                  ->references('id')
                  ->on('tenants')
                  ->onDelete('cascade');
});

and then in your migrations use:

Schema::create('users', function (Blueprint $table) {
    //..normal schema functions
    $table->tenantable();
});

having looked at the schema and builder classes i know this wouldnt work for interacting with the db nativley as the grammer used is seperated out into its own class, but we could still use blueprint base functions without issue and creating a macro would just be like grouping a few definitions together but gives a more descriptive definition "in code"

this could be especially useful for foreign key columns and indexes like above, but also for apps where 1 model has multiple relationships. here comes the expected blog example ;-)

Blueprint::macro('hasPost', function(Blueprint $table){
    $table->integer('post_id')->unsigned();
    $table->foreign('post_id')
                  ->references('id')
                  ->on(posts')
                  ->onDelete('cascade');
});

// then
Schema::create('comments', function (Blueprint $table) {
    //..normal schema functions
    $table->hasPost();
});
Schema::create('likes', function (Blueprint $table) {
    //..normal schema functions
    $table->hasPost();
});
Schema::create('images', function (Blueprint $table) {
    //..normal schema functions
    $table->hasPost();
});

as far as im aware adding something like this would be relativly simple and shouldnt cause any breaking changes. if generally accepted id be happy to get something ready for a pull request.

All 4 comments

Currently to extend the Blueprint class you would have to do first:

class ExtendedBlueprint extends Illuminate\Database\Schema\Blueprint
{
    ...
}

... then:

$newInstance = Schema::getFacadeRoot();

$newInstance->blueprintResolver(function ($table, $callback = null) {
    return new ExtendedBlueprint($table, $callback);
});

$newInstance->create('foobar', function ($table) {
    ...
});

Indeed, maybe this should be streamlined.

Or just drop in a trait?

how would that look with a trait? not quite sure how you mean?

Inserting a trait would require extending the class as well. The difficulty is about injecting the custom class.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

YannPl picture YannPl  路  3Comments

SachinAgarwal1337 picture SachinAgarwal1337  路  3Comments

ghost picture ghost  路  3Comments

Anahkiasen picture Anahkiasen  路  3Comments

lzp819739483 picture lzp819739483  路  3Comments