【问题标题】:Laravel 5: Integrity constraint violation: 1062 - Many to ManyLaravel 5:违反完整性约束:1062 - 多对多
【发布时间】:2015-12-02 01:24:06
【问题描述】:

我需要一些关于以下方面的建议。

我有 2 个迁移,就像这样。

        Schema::create('plates', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('serial_number');
        $table->string('crc-code', 50);
        $table->string('reason', 50)->nullable();

        $table->softDeletes();

        $table->timestamps();
    });

还有一个

  Schema::create('documents', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name', 25)->unique();
        $table->text('description')->nullable();
        $table->longText('relative_path');

我这样设置的多对多关系的数据透视表

        Schema::create('document_plate', function (Blueprint $table) {
      $table->integer('plate_id')->unsigned()->index();
      $table->integer('document_id')->unsigned()->index();

      $table->primary(['plate_id', 'document_id']);

      $table->timestamps();
    });

当采取某种行动时,我使用下面的代码将plate 附加到document

       $plate  =   Plate::find(1);
       $doc    =   Document::find(1);
       if($plate && $doc) {
          $plate->documents()->attach($doc->id);
       }

第一次,一切正常! document_plate 得到更新。再次使用相同的ids 时会发生错误。

SQLSTATE[23000]:完整性约束违规:1062 键“PRIMARY”的重复条目“1-1”(SQL:插入document_platecreated_atdocument_idplate_idupdated_at

现在是问题

有没有办法避免出错,只需使用相同的ids 更新表??

或者.. 我需要在前端设置某种验证,告诉用户(在提交之前)他/她选择了相同的id's,它们已经在表中。

注意:我使用 AngularJS 进行前端操作。

【问题讨论】:

  • 看起来 Laravel 不只是自动处理这个问题,除非在使用 ->sync([ids]) 的情况下。但是,绕过并不难(只是遗憾) - 只需先查询存在。但我最好的建议是看看您是否可以将代码更改为使用->sync() 而不是->attach()。它在一个地方处理数据透视表中的添加、更新和删除。您只需要在流程结束时获得所需的完整 ID 列表(因此,如果您只想添加 - 如果不存在,这并不理想)。
  • @alexrussell 只是跟进。如果上面有我的代码,你会怎么做? $plate->documents()->sync(); 当然不行。
  • sync() 要求将所有应附加的 id 传递到数组中。任何未包含在该数组中的 id 都将被删除。
  • 我也很确定 eloquent dosent 支持复合主键 github.com/laravel/framework/issues/5355 所以你需要给 document_plate 表提供主 ID

标签: php laravel


【解决方案1】:

Laravel 使用 sync 方法让这个实现变得非常简单。默认情况下,sync 方法将分离您未传递给它的任何 id,但它接受可以禁用分离的第二个参数。

$plate->documents()->sync([$doc->id], false);

这只会添加表中尚不存在的条目。

API 链接:http://laravel.com/api/5.1/Illuminate/Database/Eloquent/Relations/BelongsToMany.html#method_sync

【讨论】:

  • 啊,我不知道这一点,我什至在上面写评论时正在查看代码。德普。好地方。
  • 这些文档的链接已过时且已损坏,但我确实通过阅读最新文档解决了我的问题:laravel.com/docs/8.x/…。对于上面的示例,等效项是 $user->roles()->syncWithoutDetaching([1, 2, 3]);,但是解决我的完整性问题的一点是将关系 ID 与额外的数据透视数据分开 - $user->roles()->sync([1 => ['expires' => true], 2, 3]);
猜你喜欢
  • 2016-03-16
  • 2016-05-25
  • 2015-07-17
  • 2014-09-16
  • 1970-01-01
  • 2019-04-12
  • 2016-11-22
  • 1970-01-01
相关资源
最近更新 更多