Laravel 保存/更新多对多关系

有人能帮我拯救多对多的关系吗?我有任务,用户可以有很多任务,任务可以有很多用户(多对多) ,我想做的是,在 更新表格管理员可以分配多个用户的具体任务。这是通过 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));
}
}
}

这是表的结构 任务 截止日期

user_tasks
id|task_id|user_id
129484 次浏览

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.

tldr; Use sync with 2nd param false


Many-to-many relationship is belongsToMany on both models:

// 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.

Difference between the two is:

1 attach 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:

User and Exam linked with pivot table 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]

2 sync on the other hand, will either remove all relations and set them up anew:

$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:

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

Here's my notes on how to save and update on all the Eloquent relationships.

in One to One:

You have to use HasOne on the first model and BelongsTo on the second model

to add record on the first model (HasOne) use the save function

example:    $post->comments()->save($comment);

to add record on the second model (BelongsTo) use the associate function

example:    $user->account()->associate($account);    $user->save();


in One to Many:

You have to use HasMany on the first model and BelongsTo on the second model

to add record on the first table (HasMany) use the save or saveMany functions

example:    $post->comments()->saveMany($comments);

to add record on the second model (BelongsTo) use the associate function

example:    $user->account()->associate($account);    $user->save();


in Many to Many:

You have to use BelongsToMany on the first model and BelongsToMany on the second model

to add records on the pivot table use attach or sync functions

  • 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

example: $user->roles()->attach($roleId);


in Polymorphic One to Many:

You have to use MorphMany on the main model and MorphTo on all the (***able) models

to add records on all the other models use the save

example:    $course->tags()->save($tag);

the pivot table should have the following columns:

. main model ID

. (***able) ID

. (***able) Type


in Polymorphic Many to Many:

You have to use MorphByMany on the main model and MorphToMany on all the (***able) models

to add records on all the other models use the save or saveMany

example:    $course->tags()->save($tag);

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

the pivot table should have the following columns:

. main model ID

. (***able) ID

. (***able) Type


in Has Many Through (shortcut):

You have to use HasManyThrough on the first table and have the normal relations on the other 2 tables

this doesn’t work for ManyToMany relationships (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

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!

Solved: Use the updateOrInsert(array $attributes, array $values = [])

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



],[


'otherColumn' => $otherVlaue,
                   

]);
            



}

for those who are searching for adding pivot attributes (the middle table attributes), you can use syncWithPivotValues and it also has the second parameter like this

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