任何人都可以帮我解决如何保存多对多的关系吗?我有任务,用户可以有很多任务,任务可以有很多用户(多对多),我想要实现的是更新表格管理员可以为多个用户分配特定任务。这是通过html多选输入
完成的name="taskParticipants[]"
这里的问题是,通过相同的表单(输入),您可以添加/删除用户,这就是我必须使用sync()的原因。 也许我应该从头开始,但不知道从哪里开始...
这是我的用户模型:
public function tasks()
{
return $this->belongsToMany('Task','user_tasks');
}
任务模型
public function taskParticipants()
{
return $this->belongsToMany('User','user_tasks');
}
TaskController
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 |标题|期限
user_tasks
id|task_id|user_id
答案 0 :(得分:149)
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]
答案 1 :(得分:78)
以下是关于如何保存和更新所有Eloquent关系的笔记。
一对一:
您必须在第一个模型上使用 HasOne ,在第二个模型上使用 BelongsTo
在第一个模型上添加记录( HasOne )使用保存功能
示例:$post->comments()->save($comment);
在第二个模型上添加记录( BelongsTo )使用关联功能
示例:$user->account()->associate($account); $user->save();
一对多:
您必须在第一个模型上使用 HasMany ,在第二个模型上使用 BelongsTo
在第一个表格中添加记录( HasMany )使用保存或 saveMany 功能
示例:$post->comments()->saveMany($comments);
在第二个模型上添加记录( BelongsTo )使用关联功能
示例:$user->account()->associate($account); $user->save();
多对多:
您必须在第一个模型上使用 BelongsToMany ,在第二个模型上使用 BelongsToMany
使用附加或同步功能
在数据透视表上添加记录这两个函数都接受单个ID或ID的数组
不同之处在于附加检查,如果同步时记录已存在于数据透视表中
例如:$user->roles()->attach($roleId);
Polymorphic One to Many :
您必须在主模型上使用 MorphMany ,并在所有(***)模型上使用 MorphTo
要在所有其他模型上添加记录,请使用保存
示例:$course->tags()->save($tag);
数据透视表应包含以下列:
。主要型号ID
。 (***)ID
。 (***)类型
Polymorphic Many to Many :
您必须在主模型上使用 MorphByMany ,并在所有(***)模型上使用 MorphToMany
要在所有其他模型上添加记录,请使用保存或 saveMany
示例:$course->tags()->save($tag);
示例:$course->tags()->saveMany([$tag_1, $tag_2, $tag_3]);
数据透视表应包含以下列:
。主要型号ID
。 (***)ID
。 (***)类型
有很多通过(快捷方式):
您必须在第一个表上使用 HasManyThrough ,并在其他2个表上使用正常关系
这不适用于 ManyToMany 关系(其中有一个数据透视表)
然而,这是一个很好的解决方案。
这是我写的一篇文章,受到这个答案的启发。重要的是检查它:https://hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209
答案 2 :(得分:1)
syncWithoutDetaching([$id_one, $id_two, $id_three]);
是您要寻找的。实际上,它确实可以完成[{sync
和第二个参数false
]所做的事情!
答案 3 :(得分:1)
已解决:使用 updateOrInsert(array $attributes, array $values = [])
DB::table('your_pivot_table')->updateOrInsert([
'col' => $someValue
],[
'otherColumn' => $otherVlaue,
]);
}
答案 4 :(得分:0)
sync
函数消除了现有关系,并使您的数组成为整个关系列表。您希望attach
添加关系而不删除其他关系。