【问题标题】:How to use Eloquent 'saveMany' with pivot table?如何将 Eloquent 'saveMany' 与数据透视表一起使用?
【发布时间】:2016-01-06 18:00:13
【问题描述】:

在 Laravel 中,我有一个用户表和一个通知表,它们是多对多关系。每个通知都发给一组用户,每个用户都可以将通知单独标记为已读。中间表 (notice_user_map) 有一个“读取”列。

我正在尝试创建“将所有内容标记为已读”功能,但无法通过 Eloquent 看到如何做到这一点。这是基本代码:

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

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

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

因此,这会找到该用户的所有未读通知并循环访问它们,在中间(数据透视表)上设置“读取”属性。但是最后一行给出了错误

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

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

违反完整性约束:1062 键“notice_user”的重复条目“4293672207-2904708423”(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 这样访问数据透视表。

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

【问题讨论】:

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


    【解决方案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]);
    

    【讨论】:

    • 我收到一个错误:Integrity constraint violation: 1052 Column 'updated_at' in field list is ambiguous (SQL: update `notices` inner join `notice_user_map` on `notices`.`id` = `notice_user_map`.`notice_id` set `read` = 1, `updated_at` = 2016-01-06 23:49:45 where `notice_user_map`.`user_id` = 2904708423 and `notice_user_map`.`read` = 0)
    • @DisgruntledGoat 啊,对不起。如果您的数据透视表上也有时间戳,那么您将收到该错误。不知道为什么 Laravel 仍然没有为列名添加前缀,但我用另一个解决方案编辑了我的答案。
    猜你喜欢
    • 2018-02-25
    • 2020-12-10
    • 2013-09-03
    • 2016-04-11
    • 1970-01-01
    • 2019-11-05
    • 1970-01-01
    • 2012-06-09
    • 2019-01-25
    相关资源
    最近更新 更多