首页 > 解决方案 > 是否可以延长迁移?如果是这样,这是一个好习惯吗?

问题描述

我有两个在表结构方面相同的模型,但我想将它们分开以利用这样的优势:

FirstModel::all()

我的目标是让这两个模型的迁移扩展父迁移,即使它们是空的,只是出于上述原因。此外,我真的无法忍受在两个迁移文件之间复制和粘贴它们的结构。

这是父迁移:

use Illuminate\Database\Migrations\Migration;

class CreateParentModelTable extends Migration
{
     /**
      * Run the migrations.
      *
      * @return void
      */
      public function up()
      {
          Schema::create('parent_model', function (Blueprint $table) {
              $table->bigIncrements('id');
              $table->timestamps();
          });
      }

      /**
      * Reverse the migrations.
      *
      * @return void
      */
      public function down()
      {
          Schema::dropIfExists('parent_model');
      }
}

这是第一个模型迁移:

use App\Database\Migrations\CreateParentModelTable;

class CreateFirstModelTable extends CreateParentModelTable
{
    /**
    * Run the migrations.
    *
    * @return void
    */
    public function up()
    {
        Schema::create('first_model', function (Blueprint $table) {
            //
        });
    }

    /**
    * Reverse the migrations.
    *
    * @return void
    */
   public function down()
   {
       Schema::dropIfExists('first_model');
   }
}

当然,第二个模型迁移是相同的。现在......我知道这段代码不能工作,因为应该有一些东西实际上会引入父模型迁移,因为扩展它的类是不够的,但第一个问题是我收到了一个奇怪的错误:

Class 'Database\Migrations\CreateParentModelTable' not found

为什么?除此之外,这篇文章的真正问题是什么?

编辑:导入时不能使用 Laravel 自动添加的CreateParentModelTable前面的时间戳。这就是我尝试这种方式的原因。

实用解决方案:我刚刚创建了两个迁移,因为我确信它们服务于两个不同的目的,即使以相同的方式。

标签: laravel

解决方案


您不一定需要两个迁移文件。简单地说,迁移就是一批以某种方式修改数据库的操作。在迁移中更改数据库的哪些部分是您必须自己决定的。确实建议每个表使用一个迁移文件,但如果在给定场景中有意义,您也可以采用不同的方式。

如果正确完成,您的迁移类继承方法将起作用:

class CreateParentModelTable
{
    public function up()
    {
        Schema::create($this->table, function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->timestamps();
        });
    }

   public function down()
   {
       Schema::dropIfExists($this->table);
   }
}

class CreateFirstModelTable extends CreateParentModelTable
{
    protected $table = 'first_model';
}

class CreateSecondModelTable extends CreateParentModelTable
{
    protected $table = 'second_model';
}

另一种方法是使用相同的闭包和相同的选项在同一个迁移文件中创建两个表:

public function up()
{
    $tableOptions = function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->timestamps();
    };

    Schema::create('first_model', $tableOptions);
    Schema::create('second_model', $tableOptions);
}

public function down()
{
    Schema::dropIfExists('second_model');
    Schema::dropIfExists('first_model');
}

另一种解决方案是通过创建一个可以以多态方式存储两者的表来避免创建两个相等的表:

class CreatePolymorphicModelTable
{
    public function up()
    {
        Schema::create('polymorphic_model', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->enum('type', ['first', 'second']);
            $table->timestamps();
        });
    }

   public function down()
   {
       Schema::dropIfExists('polymorphic_model');
   }
}

根据表的类型(即它是否是 1:n 关系中的子表),遵守Laravel 官方文档中描述的多态表和关系指南是有意义的。


推荐阅读