Laravel 保存/更新多对多关系
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24702640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel save / update many to many relationship
提问by SuperManSL
Can anyone help me on how to save many to many relationship? I have tasks, user can have many tasks and task can have many users (many to many), What I want to achieve is that in update formadmin can assign multiple users to specific task. This is done through html multiple select input
谁能帮助我如何挽救多对多的关系?我有任务,用户可以有很多任务,任务可以有很多用户(多对多),我想要实现的是在更新表单中管理员可以将多个用户分配给特定任务。这是通过html多选输入完成的
name="taskParticipants[]"
The catch here is that through the same form (input) you can add/remove users, that's why I have to use sync(). Maybe I should start from the beginning but don't know where to start...
这里的问题是,通过相同的表单(输入),您可以添加/删除用户,这就是我必须使用 sync() 的原因。也许我应该从头开始,但不知道从哪里开始......
This is my User model:
这是我的用户模型:
public function tasks()
{
return $this->belongsToMany('Task','user_tasks');
}
Task model
任务模型
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));
}
}
}
This is structure of tablestasks id|title|deadline
这是表任务id|title|deadline的结构
user_tasks
id|task_id|user_id
回答by Jarek Tkaczyk
tldr;Use sync
with 2nd param false
tldr; sync
与第二个参数一起使用false
Many-to-many relationship is belongsToMany
on both models:
多对多关系适用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');
}
In order to add new relation use attach
or sync
.
为了添加新关系,请使用attach
或sync
。
Difference between the two is:
两者的区别在于:
1attach
will add new row on the pivot table without checking if it's already there. It's good when you have additional data linked to that relation, for example:
1attach
将在数据透视表上添加新行而不检查它是否已经存在。当您将附加数据链接到该关系时,这很好,例如:
User
and Exam
linked with pivot table attempts: id, user_id, exam_id, score
User
并Exam
与数据透视表链接attempts: id, user_id, exam_id, score
I suppose this is not what you need in your situation:
我想这不是您的情况所需要的:
$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]
2sync
on the other hand, will either remove all relations and set them up anew:
2sync
另一方面,将删除所有关系并重新设置它们:
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6]
$user->tasks()->sync([1,2,3]);
// then
$user->tasks()->getRelatedIds(); // [1,2,3]
or it will setup new relations without detaching previous AND without adding duplicates:
或者它会在不分离以前的 AND 而不添加重复项的情况下建立新的关系:
$user->tasks()->sync([5,6,7,8], false); // 2nd param = detach
// then
$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6,7,8]
回答by Mahmoud Zalt
Here's my notes on how to save and update on all the Eloquent relationships.
这是我关于如何保存和更新所有 Eloquent 关系的笔记。
in One to One:
在一对一:
You have to use HasOneon the first model and BelongsToon the second model
你必须使用HasOne上的第一款车型,并属于关联的第二个模型
to add record on the first model (HasOne) use the save?function
要在第一个模型 ( HasOne)上添加记录,请使用save? 函数
example: ?? $post->comments()->save($comment);
例子: ?? $post->comments()->save($comment);
to add record on the second model (BelongsTo) use the?associatefunction
在第二个模型(BelongsTo)上添加记录使用?关联功能
example: ? ?$user->account()->associate($account);? ??$user->save();
例子: ??$user->account()->associate($account);? ??$user->save();
in One to Many:
在一对多:
You have to use HasManyon the first model and BelongsToon the second model
你必须使用的hasMany上的第一款车型,并属于关联的第二个模型
to add record on the first table (HasMany) use the save?or saveManyfunctions
要在第一个表 ( HasMany)上添加记录,请使用save? 或saveMany函数
example: ? ?$post->comments()->saveMany($comments);
例子: ??$post->comments()->saveMany($comments);
to add record on the second model (BelongsTo) use the?associatefunction
在第二个模型(BelongsTo)上添加记录使用?关联功能
example: ? ?$user->account()->associate($account);? ??$user->save();
例子: ??$user->account()->associate($account);? ??$user->save();
in Many to Many:
在多对多中:
You have to use?BelongsToManyon the first model and BelongsToManyon the second model
你得用吗?BelongsToMany第一模型和BelongsToMany第二模型
to add records on the pivot table use attachor syncfunctions
在数据透视表上添加记录使用附加或同步功能
both?functions accepts single ID?or array of ID's?
the difference is attach checks if the record already exist on the pivot table while sync don't
两个?函数都接受单个 ID?还是 ID 数组?
不同之处在于附加检查记录是否已存在于数据透视表中,而同步则不
example:?$user->roles()->attach($roleId);
例子:?$user->roles()->attach($roleId);
in Polymorphic One to Many:
在多态一对多中:
You have?to use?MorphManyon the main model and?MorphToon all the (***able) models
你有?用?MorphMany主要模型和?MorphTo在所有 (***able) 模型上
to add records on all the other models use the?save
在所有其他模型上添加记录使用?节省
example: ? ?$course->tags()->save($tag);
例子: ??$course->tags()->save($tag);
the pivot table?should have the following?columns:
数据透视表?应该有以下?列:
. main model ID
. 主要型号标识
.?(***able) ID
.?(***能)ID
.?(***able) Type
.?(***able) 类型
in Polymorphic Many to Many:
在多态多对多中:
You have?to use?MorphByManyon the main model and?MorphToManyon all the (***able) models
你有?用?MorphByMany主要模型和?MorphToMany在所有 (***able) 模型上
to add records on all the other models use the saveor saveMany
要在所有其他模型上添加记录,请使用save或saveMany
example: ? ?$course->tags()->save($tag);
例子: ??$course->tags()->save($tag);
example: ? ?$course->tags()->saveMany([$tag_1, $tag_2, $tag_3]);
例子: ??$course->tags()->saveMany([$tag_1, $tag_2, $tag_3]);
the pivot table?should have the following?columns:
数据透视表?应该有以下?列:
. main model ID
. 主要型号标识
.?(***able) ID
.?(***能)ID
.?(***able) Type
.?(***able) 类型
in Has Many Through(shortcut):
在有很多通过(快捷方式):
You have to use HasManyThroughon the first table and have the normal relations on the other 2 tables
您必须在第一个表上使用HasManyThrough并在其他 2 个表上具有正常关系
this doesn't work for ManyToManyrelationships (where there's a pivot table)
这不适用于多对多关系(有数据透视表的地方)
however there's a nice and easy solution just for that.
但是,有一个很好且简单的解决方案。
Here's an article I wrote, inspired by this answer. Important to check it: https://hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209
这是我写的一篇文章,灵感来自这个答案。检查它很重要:https: //hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209
回答by Moslem Deris
syncWithoutDetaching([$id_one, $id_two, $id_three]);
is what you are looking for. Actually it does the exact thing [sync
with 2nd param false
] does!
syncWithoutDetaching([$id_one, $id_two, $id_three]);
就是你要找的。实际上,它与 [sync
带有 2nd param false
] 的功能完全相同!
回答by ceejayoz
The sync
function obliterates the exiting relationships and makes your array the entire list of relations. You want attach
instead to add relations without removing others.
该sync
函数删除现有关系并使您的数组成为整个关系列表。您希望attach
在不删除其他关系的情况下添加关系。