如何使用Eloquent' saveMany'使用数据透视表?

时间:2016-01-06 18:00:14

标签: php mysql laravel eloquent many-to-many

在Laravel中,我有一个用户表和一个通知表,以多对多的关系。每个通知都发给一组用户,每个用户都可以将通知标记为独立读取。中间表(notice_user_map)有一个'读取'专栏。

我试图创建"将所有标记为已读"功能,但无法通过Eloquent了解如何做到这一点。这是基本代码:

$notices = $user->notices()
    ->where('read', 0)
    ->get();

foreach ($notices as $notice) {
    $notice->pivot->read = 1;
}

$authUser->notices()->saveMany($notices);

因此,这会找到该用户的所有未读通知并循环播放,然后设置' read'中间(数据透视)表的属性。但最后一行给出了错误

  

传递给Illuminate \ Database \ Eloquent \ Relations \ BelongsToMany :: saveMany()的参数1必须是类型数组,给定对象

如果我手动创建一个数组,我会收到此错误:

  

完整性约束违规:1062重复条目' 4293672207-2904708423'对于密钥' notice_user' (SQL:插入notice_user_mapcreated_atnotice_idupdated_atuser_id)值(2016-01-06 17:53:39,4293672207, 2016-01-06 17:53:39,2904708423))

我无法像$authUser->notices()->pivot那样访问枢轴。

在数据透视表中批量保存数据的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

您可以更新它而不是检索值然后循环它们。尝试这样的事情:

$user->notices()->wherePivot('read', 0)->update(['read' => 1]);

这最终应该遵循查询构建器并在单个查询中更新数据透视表,而不是循环并创建大量查询。

编辑:如果您的数据透视表也有时间戳,那么这将抛出一个错误,因为Eloquent没有为这些列名添加前缀(不确定原因)。在这种情况下,您仍然可以使用查询构建器实现此目的:

DB::table('notice_user_map')
    ->where('user_id', $user->id)
    ->where('read', 0)
    ->update(['read' => 1]);