Laravel-无法迁移具有1:N和1:1关系的表

时间:2018-07-09 08:26:43

标签: php laravel migration

我有以下迁移表:

class CreateQuizzesTable extends Migration
{
    public function up()
    {
        Schema::create('quizzes', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('customer_id')->unsigned()->nullable();
            $table->string('name');
            $table->foreign('customer_id')->references('id')->on('customers')->onDelete('set null');
        });
    }

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

还有

class CreateCustomersTable extends Migration
{
    public function up()
    {
        Schema::create('customers', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('quiz_id')->unsigned()->nullable();
            $table->string('name')->unique();
            $table->string('password');
            $table->foreign('quiz_id')->references('id')->on('quizzes')->onDelete('set null');
        });
    }

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

客户可以创建(因此拥有)多个测验(1:N)。 客户表具有 quiz_id 字段的原因是,在他创建的那些字段中,一次只能激活一个(1:1)。

问题在于,当我尝试迁移时,它崩溃了,因为两个表相互引用,并通知我另一个表尚不存在。

如果我将 CreateQuizzesTable 设置为首先执行:

  

SQLSTATE [42P01]:未定义表:7错误:关系不存在«客户»

如果我将 CreateCustomersTable 设置为首先执行:

  

SQLSTATE [42P01]:未定义表:7错误:关系不存在«测验»

我坚持认为,这不是N:M关系,我想避免使用中间表来对此进行管理。

更新:签出@JasperStaats答案后,我仍然对表的播种有问题。由于必须先执行两个表播种器之一,因此它期望另一个表的外键值已经存在于数据库中(例如:如果我先执行QuizzesTableSeeder,它将无法插入值'customer_id'= > 1,因为客户表仍然为空。现在,我将该字段值保留为空,然后转到DB并将其替换为适当的值,但这并不理想。

种子执行命令文件:

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        $this->call(QuizzesTableSeeder::class);
        $this->call(CustomersTableSeeder::class);
    }
}

客户种子文件:

use Illuminate\Database\Seeder;

class CustomersTableSeeder extends Seeder
{
    public function run()
    {
        \DB::table('customers')->delete();

        \DB::table('customers')->insert(array(
            0 =>
            array(
                'id' => 1,
                'quiz_id' => 1,
                'name' => 'user1',
                'password' => 'pass1'
            )
        ));
    }
}

测验种子文件:

use Illuminate\Database\Seeder;

class QuizzesTableSeeder extends Seeder
{
    public function run()
    {
        \DB::table('quizzes')->delete();

        \DB::table('quizzes')->insert(array(
            0 =>
            array(
                'id' => 1,
                'customer_id' => 1,
                'name' => 'quizz1',
            )
        ));
    }
}

1 个答案:

答案 0 :(得分:1)

我建议您先迁移表,然后再进行新迁移以使用外键。

php artisan make:migration add_foreign_keys

然后

class AddForeignKeysTable extends Migration
    {
        public function up()
        {
            Schema::table('customers', function (Blueprint $table) {

                $table->foreign('quiz_id')->references('id')->on('quizzes')->onDelete('set null');
            });

            Schema::table('quizzes', function (Blueprint $table) {
                $table->foreign('customer_id')->references('id')->on('customers')->onDelete('set null');
            });


        }

        public function down()
        {
            Schema::table('customers',function(Blueprint $table){
                // Place foreign key name
                $table->dropForeign('FOREIGN_KEY_NAME');
            });

            Schema::table('quizzes',function(Blueprint $table){
                // Place foreign key name
                $table->dropForeign('FOREIGN_KEY_NAME');
            });
        }
    }

这样,您可以确保如果存在表,则将添加外键