laravel / ideas

Issues board used for Laravel internals discussions.
938 stars 28 forks source link

[Migrations] Add blueprintResolver setting in Migration class #1241

Open lozovoyv opened 6 years ago

lozovoyv commented 6 years ago

I think it would be very useful improvement for creating databases. This will help not to copy-paste lots of strings like $table->string('meta_title')->nullable() and so on, but use one or several blueprints libraries via packages or simple coping from project to project and incredibly speedup database developing with minimum type hints.

I make additional classes for myself:

class MyBlueprint extends Blueprint
{
    /**
     * Add SEO attributes to the table.
     *
     * @return  void
     */
    public function seo()
    {
        $this->string('meta_title')->nullable();
        $this->string('meta_keywords')->nullable();
        $this->text('meta_description')->nullable();
    }
   ...
abstract class MyMigration extends Migration
{
    protected $blueprint;

    protected $schema;

    public function __construct()
    {
        $this->schema = app()->make('db')->connection()->getSchemaBuilder();

        if($this->blueprint) {
            $this->schema->blueprintResolver(function ($table, $callback) {
                return new $this->blueprint($table, $callback);
            });
        }
    }
}

and then use it

class CreatePagesTable extends MyMigration
{
    protected $blueprint = MyBlueprint::class;

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        $this->schema->create('pages', function (MyBlueprint $table) {

            $table->increments('id');
            $table->string('name')->nullable();

            $table->publication();
            $table->seo();
            $table->robots();
            $table->sitemap();
            ...

Of course, this is not best solution in whole framework's architecture concepts, but it solves my problems. I had not dig framework sources so deep to check compatibility with different db connections. I`m using only default connection.

Patryk27 commented 6 years ago

What do you do when you want to update the blueprint, without touching the old (already existing) migrations?

lozovoyv commented 6 years ago

@Patryk27 Typically I define functions for one or several columns that are coming together. Looks like $table->timestamps() creates two columns and $table->softdeletes() creates one. When is needed to add, modify or delete some column it can be done as usual. Just add migration that does changes.

lagbox commented 6 years ago

Blueprint has macros to add functionality without needing to extend, side note.