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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 02:52:41  来源:igfitidea点击:

Laravel save / update many to many relationship

laravellaravel-4eloquentrelationship

提问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 syncwith 2nd param false

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



Many-to-many relationship is belongsToManyon 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 attachor sync.

为了添加新关系,请使用attachsync

Difference between the two is:

两者的区别在于:

1attachwill 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将在数据透视表上添加新行而不检查它是否已经存在。当您将附加数据链接到该关系时,这很好,例如:

Userand Examlinked with pivot table attempts: id, user_id, exam_id, score

UserExam与数据透视表链接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]


2syncon 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

你有?用?MorphBy​​Many主要模型和?MorphToMany在所有 (***able) 模型上

to add records on all the other models use the saveor saveMany

要在所有其他模型上添加记录,请使用savesaveMany

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 [syncwith 2nd param false] does!

syncWithoutDetaching([$id_one, $id_two, $id_three]);就是你要找的。实际上,它与 [sync带有 2nd param false] 的功能完全相同!

回答by ceejayoz

The syncfunction obliterates the exiting relationships and makes your array the entire list of relations. You want attachinstead to add relations without removing others.

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