如何将 Eloquent 'saveMany' 与 pivot table 一起使用?

How to use Eloquent 'saveMany' with pivot table?

在 Laravel 中,我有一个 table 个用户和一个 table 个通知,处于多对多关系中。每个通知都发给一组用户,每个用户都可以将通知标记为独立已读。中间 table (notice_user_map) 为此有一个 'read' 列。

我正在尝试创建 "mark all as read" 功能,但看不到如何通过 Eloquent 执行此操作。这是基本代码:

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

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

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

所以这会找到该用户的所有未读通知并循环遍历它们,在中间(枢轴)table 上设置 'read' 属性。但是最后一行给出了错误

Argument 1 passed to Illuminate\Database\Eloquent\Relations\BelongsToMany::saveMany() must be of the type array, object given

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

Integrity constraint violation: 1062 Duplicate entry '4293672207-2904708423' for key 'notice_user' (SQL: insert into notice_user_map (created_at, notice_id, updated_at, user_id) values (2016-01-06 17:53:39, 4293672207, 2016-01-06 17:53:39, 2904708423))

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

在 pivot table 中大量保存数据的正确方法是什么?

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

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

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

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

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