是否可以扩展迁移?如果是这样,这是一个好习惯吗?

时间:2019-04-08 09:55:20

标签: laravel

我有两个表结构相同的模型,但是我想将它们分开以利用诸如此类的优势:

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 前面的时间戳。这就是为什么我尝试这种方式。

实际解决方案:我刚刚创建了两个迁移,因为我确信即使它们采用相同的方式,它们也有两个不同的用途。

1 个答案:

答案 0 :(得分:0)

您不一定需要两个迁移文件。简而言之,迁移就是一批以某种方式修改数据库的操作。您必须自行决定要在迁移中更改数据库的哪些部分。确实,建议每个表使用一个迁移文件,但是如果在给定的情况下有意义,那么您也可以采用其他方法。

如果正确完成,您的方法可以继承迁移类:

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 documentation中所述的多态表和关系准则。