谁能帮助我如何挽救多对多的关系?我有任务,用户可以有很多任务,任务可以有很多用户(多对多),我想要实现的是在更新表单中管理员可以将多个用户分配给特定任务。这是通过 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
$workers = Input::get('taskParticipants'); $task->taskParticipants()->sync($workers);
这就是您所需要的,只要您从该表单传递分配给任务的所有用户。
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');
}
要添加新关系,请使用 attach
或 sync
。
两者的区别在于:
1 attach
将在数据透视表上添加新行,而不检查它是否已经存在。当您有其他数据链接到该关系时,这很好,例如:
User
和 Exam
与数据透视表 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]
这是我关于如何保存和更新所有 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
updateMany
这样的记录?谢谢
syncWithoutDetaching([$id_one, $id_two, $id_three]);
是您要查找的内容。实际上,它确实做了 [sync
with 2nd param false
] 所做的事情!
已解决:使用 updateOrInsert(array $attributes, array $values = [])
DB::table('your_pivot_table')->updateOrInsert([
'col' => $someValue
],[
'otherColumn' => $otherVlaue,
]);
}
sync
函数消除现有关系并使您的数组成为整个关系列表。您希望 attach
添加关系而不删除其他关系。
对于那些正在搜索添加枢轴属性(中间表属性)的人,您可以使用 syncWithPivotValues 并且它还具有像这样的第二个参数
$user->tasks()->syncWithPivotValues($tasksIDs,['day_number' => $day],false);
task_user
而不是user_tasks
),则可以将关系查询简化为$this->belongsToMany('User')
sync
进行分离,不用担心。当您传递相关模型的单个id
时,我建议您在想要“为用户添加新任务”或“将用户分配给任务”时使用设置为 false 的第二个参数。sync
返回一个包含detached
、attached
和updated
列表的数组。attach
不返回任何内容,但在这两种情况下,如果在 db 调用中发生意外情况,您都会收到异常。