【问题标题】:Use trait in Laravel database migration在 Laravel 数据库迁移中使用 trait
【发布时间】:2019-11-18 18:34:21
【问题描述】:

我的上级告诉我,我可以创建一个seeder 类似trait,然后我可以在migration 中使用它。在服务器上运行迁移时,数据库会在迁移时自动播种,而不是在迁移成功后运行单独的播种器。

现在我创建了一个包含在数据库迁移中的特征。

<?php

namespace App\Services;

use App\Models\Module\Module;
use App\Models\Plan\Plan;

/**
 * PlanAndModuleGenerator class.
 */
trait PlanAndModuleGenerator
{
    private static $plans = [
        'free',
        'basic',
        'premium',
    ];

    public function up()
    {

        foreach ($this->plans as $planName) {

            // Get or create Plan.
            $plan = Plan::create([
                'machine_name' => '',
                'name' => $planName
            ]);
        }
    }
}

我的上级告诉我他们以前这样做过,但我在互联网上找不到类似的东西。我把我的特质包括在内。

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use App\Services\PlanAndModuleGenerator;

class ModulePlan extends Migration
{
    use PlanAndModuleGenerator;
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('module_plan', function (Blueprint $table) {
            $table->unsignedInteger('plan_id');
            $table->unsignedInteger('module_id');

            $table->foreign('plan_id')->references('id')->on('plans');
            $table->foreign('module_id')->references('id')->on('modules');
        });
    }

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

当我运行迁移时,trait 中的 up 函数不会执行。我知道这一点是因为 Plan 表尚未播种。关于我如何解决这个问题的任何想法?由于我的上级在接下来的几天里不在办公室,我无法访问他们之前执行此操作的存储库。

除此之外,谁能告诉我如何正确调试此特征?我现在这样做的方式,只是运行迁移并等待错误,似乎有点麻烦。

【问题讨论】:

标签: laravel database-migration traits


【解决方案1】:

我根本看不出这个特性有任何原因,但如果你真的想使用它,你需要给特性的 up 方法加上别名,然后在你的 up 迁移方法中调用它:

class ModulePlan extends Migration
{
    use PlanAndModuleGenerator { up as traitUp; }

    public function up()
    {
        ...
        $this->traitUp();
    }
}

最好为 Trait 中的方法使用不同的名称,但从一开始,这个 trait 似乎没有任何理由。

【讨论】:

    【解决方案2】:

    这肯定行不通,因为您有两个up 方法,一个在您的trait 中,一个在您的migration 中。您需要在迁移中删除 up 并在您的 trait 中使用它,如下所示。这是特点

    <?php
    
    namespace App\Services;
    
    
    use App\Models\Plan\Plan;
    use App\Models\Module\Module;
    use Illuminate\Support\Facades\Schema;
    use Illuminate\Database\Schema\Blueprint;
    
    /**
     * PlanAndModuleGenerator class.
     */
    trait PlanAndModuleGenerator
    {
        private static $plans = [
            'free',
            'basic',
            'premium',
        ];
    
        public function up()
        {
            $createmigration = Schema::create('module_plan', function (Blueprint $table) {
                $table->unsignedInteger('plan_id');
                $table->unsignedInteger('module_id');
    
                $table->foreign('plan_id')->references('id')->on('plans');
                $table->foreign('module_id')->references('id')->on('modules');
            });
    
            if ($createmigration) {
                foreach ($this->plans as $planName) {
                    // Get or create Plan.
                    $plan = Plan::create([
                        'machine_name' => '',
                        'name' => $planName
                    ]);
                }
            }
        }
    }

    在创建计划之前先确认迁移已创建。

    这是您的迁移应该是什么样子的

    <?php
    
    use Illuminate\Support\Facades\Schema;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;
    use App\Services\PlanAndModuleGenerator;
    
    class ModulePlan extends Migration
    {
        use PlanAndModuleGenerator;
        
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('module_plan');
        }
    }

    希望这会有所帮助

    【讨论】:

    • 那时为什么要使用该特征,为什么不在迁移中全部使用呢?现在,如果不深入研究特征,您将无法看到您的架构
    • Illuminate\Database\Schema\Builder@create 返回无效
    • 谢谢,我不知道它返回void,不过@Baspa 的问题是两次使用up 方法。
    猜你喜欢
    • 2014-06-05
    • 2018-04-04
    • 2020-05-07
    • 2016-12-09
    • 2018-04-06
    • 2016-02-28
    • 1970-01-01
    • 2019-10-10
    • 1970-01-01
    相关资源
    最近更新 更多