Laravel保存/更新多对多的关系

时间:2014-07-11 16:42:42

标签: laravel laravel-4 eloquent relationship

任何人都可以帮我解决如何保存多对多的关系吗?我有任务,用户可以有很多任务,任务可以有很多用户(多对多),我想要实现的是更新表格管理员可以为多个用户分配特定任务。这是通过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

5 个答案:

答案 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');
}

要添加新关系,请使用attachsync

两者之间的区别是:

1 attach会在数据透视表上添加新行,而不会检查它是否已存在。当您有其他数据链接到该关系时,这很好,例如:

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

您必须在主模型上使用 MorphBy​​Many ,并在所有(***)模型上使用 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添加关系而不删除其他关系。