ChatGPT解决这个技术问题 Extra ChatGPT

Laravel 保存/更新多对多关系

谁能帮助我如何挽救多对多的关系?我有任务,用户可以有很多任务,任务可以有很多用户(多对多),我想要实现的是在更新表单中管理员可以将多个用户分配给特定任务。这是通过 html 多选输入完成的

name="taskParticipants[]"

这里要注意的是,通过相同的表单(输入),您可以添加/删除用户,这就是我必须使用 sync() 的原因。也许我应该从头开始,但不知道从哪里开始......

这是我的用户模型:

public function tasks()
{
    return $this->belongsToMany('Task','user_tasks');
}

任务模型

public function taskParticipants()
{
    return $this->belongsToMany('User','user_tasks');
}

任务控制器

public function update($task_id)
{
    if (Input::has('taskParticipants'))
    {
        foreach(Input::get('taskParticipants') as $worker)
        {
            $task2 = $task->taskParticipants->toArray();
            $task2 = array_add($task2,$task_id,$worker);
            $task->taskParticipants()->sync(array($task2));
        }
    }
}

这是表任务 id|title|deadline 的结构

user_tasks
id|task_id|user_id
我已经更新了我的代码。 link
$workers = Input::get('taskParticipants'); $task->taskParticipants()->sync($workers); 这就是您所需要的,只要您从该表单传递分配给任务的所有用户。
@JarekTkaczyk 谢谢,那太神奇了。

A
Alexxus

tldr;sync 与第二个参数 false 一起使用

两个模型上的多对多关系都是 belongsToMany

// Task model
public function users()
{
  return $this->belongsToMany('User', 'user_tasks'); // assuming user_id and task_id as fk
}

// User model
public function tasks()
{
  return $this->belongsToMany('Task', 'user_tasks');
}

要添加新关系,请使用 attachsync

两者的区别在于:

1 attach 将在数据透视表上添加新行,而不检查它是否已经存在。当您有其他数据链接到该关系时,这很好,例如:

UserExam 与数据透视表 attempts: id, user_id, exam_id, score 链接

我想这不是你在你的情况下需要的:

$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6]

$user->tasks()->attach([5,6,7]);
// then
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6,5,6,7]

另一方面,2 sync 将删除所有关系并重新设置它们:

$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6]

$user->tasks()->sync([1,2,3]);
// then
$user->tasks()->getRelatedIds(); // [1,2,3]

或者它将设置新的关系而不分离以前的 AND 而不添加重复项:

$user->tasks()->sync([5,6,7,8], false); // 2nd param = detach
// then
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6,7,8]

如果将其记录在主文档而不是 API 文档中,那就太好了!摇滚吧。 +1。
我真的很喜欢带有同步和第二个参数的第二个解决方案。就像我在下面的评论中说的那样,我不能不使用分离。故事是管理员可以将任务分配给用户。他从下拉列表中选择用户(多个),字段是参与者[]。所以...:第 1 步:管理员将任务 A 分配给三个用户(您的方法有效,我们在 DB 中有 3 条记录) 第 2 步:管理员更新任务 A 并添加两个用户(您的方法有效,我们在 DB 中有 5 条记录)第 3 步:管理员更新任务 A 并删除 1 个用户(您的方法失败,我们仍然有 5 个用户而不是 4 个)my update method my code
如果您使用按字母顺序和单数顺序命名表(因此 task_user 而不是 user_tasks),则可以将关系查询简化为 $this->belongsToMany('User')
@Rok,如果您始终传递所有相关用户的数组,则使用 sync 进行分离,不用担心。当您传递相关模型的单个 id 时,我建议您在想要“为用户添加新任务”或“将用户分配给任务”时使用设置为 false 的第二个参数。
@FabioAntunes sync 返回一个包含 detachedattachedupdated 列表的数组。 attach 不返回任何内容,但在这两种情况下,如果在 db 调用中发生意外情况,您都会收到异常。
M
Mahmoud Zalt

这是我关于如何保存和更新所有 Eloquent 关系的笔记。

一对一:

您必须在第一个模型上使用 HasOne,在第二个模型上使用 BelongsTo

在第一个模型(HasOne)上添加记录使用保存功能

示例:   $post->comments()->save($comment);

要在第二个模型 (BelongsTo) 上添加记录,请使用 associate 函数

示例:   $user->account()->associate($account);    $user->save();

一对多:

您必须在第一个模型上使用 HasMany,在第二个模型上使用 BelongsTo

在第一个表 (HasMany) 上添加记录使用 save 或 saveMany 函数

示例:   $post->comments()->saveMany($comments);

要在第二个模型 (BelongsTo) 上添加记录,请使用 associate 函数

示例:   $user->account()->associate($account);    $user->save();

在多对多中:

您必须在第一个模型上使用 BelongsToMany,在第二个模型上使用 BelongsToMany

在数据透视表上添加记录使用附加或同步功能

这两个函数都接受单个 ID 或 ID 数组

不同之处在于附加检查记录是否已存在于数据透视表中,而同步不存在

示例: $user->roles()->attach($roleId);

在多态一对多中:

您必须在主模型上使用 MorphMany,在所有(***able)模型上使用 MorphTo

在所有其他模型上添加记录使用保存

示例:   $course->tags()->save($tag);

数据透视表应具有以下列:

.主要型号标识

(***能)身份证

(***able) 类型

在多态多对多中:

您必须在主模型上使用 MorphByMany,在所有(***able)模型上使用 MorphToMany

在所有其他模型上添加记录使用 save 或 saveMany

示例:   $course->tags()->save($tag);

示例:   $course->tags()->saveMany([$tag_1, $tag_2, $tag_3]);

数据透视表应具有以下列:

.主要型号标识

(***能)身份证

(***able) 类型

在有很多通过(快捷方式):

您必须在第一个表上使用 HasManyThrough 并在其他 2 个表上具有正常关系

这不适用于多对多关系(有数据透视表的地方)

但是,为此有一个很好且简单的解决方案。

这是我写的一篇文章,灵感来自这个答案。重要检查:https://hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209


当他们已经在正确答案上获得超过 40 个赞时,我实际上放置了这个答案,但是是的,我知道这对我有多大用处,很高兴你喜欢它 :)
如何更新一个到可能的关系。你解释了如何添加。你能解释一下更新吗?有没有办法更新像 updateMany 这样的记录?谢谢
M
Moslem Deris

syncWithoutDetaching([$id_one, $id_two, $id_three]); 是您要查找的内容。实际上,它确实做了 [sync with 2nd param false] 所做的事情!


H
Hashmat Waziri

已解决:使用 updateOrInsert(array $attributes, array $values = [])

     DB::table('your_pivot_table')->updateOrInsert([
                'col' => $someValue
                

            ],[

                    'otherColumn' => $otherVlaue,
                   
                ]);
            

        }

c
ceejayoz

sync 函数消除现有关系并使您的数组成为整个关系列表。您希望 attach 添加关系而不删除其他关系。


我不能使用附加,因为我在更新方法中使用了这个代码。故事是管理员可以更新任务并用将参与任务的用户填写输入参与者[]。所以我需要检查它是否存在并删除(或不添加新记录)或者如果它不存在添加它。
R
Rama Ranneh

对于那些正在搜索添加枢轴属性(中间表属性)的人,您可以使用 syncWithPivotValues 并且它还具有像这样的第二个参数

$user->tasks()->syncWithPivotValues($tasksIDs,['day_number' => $day],false);

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅