【问题标题】:Laravel save / update many to many relationshipLaravel 保存/更新多对多关系
【发布时间】:2014-09-02 08:51:12
【问题描述】:

任何人都可以帮助我如何保存多对多关系吗?我有任务,用户可以有很多任务,任务可以有很多用户(多对多),我想要实现的是在 更新表单 管理员可以将多个用户分配给特定任务。这是通过html多选输入来完成的

name="taskParticipants[]"

这里的问题是通过相同的表单(输入)您可以添加/删除用户,这就是我必须使用sync() 的原因。 也许我应该从头开始,但不知道从哪里开始......

这是我的用户模型:

public function tasks()
{
    return $this->belongsToMany('Task','user_tasks');
}

任务模型

public function taskParticipants()
{
    return $this->belongsToMany('User','user_tasks');
}

任务控制器

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|title|截止日期

user_tasks
id|task_id|user_id

【问题讨论】:

  • 我已经更新了我的代码。 link
  • $workers = Input::get('taskParticipants'); $task->taskParticipants()->sync($workers); 这就是您所需要的,只要您从该表单传递所有分配给任务的用户。
  • @JarekTkaczyk 谢谢,这太神奇了。

标签: laravel laravel-4 eloquent relationship


【解决方案1】:

sync 函数消除现有关系并使您的数组成为整个关系列表。您希望 attach 代替添加关系而不删除其他关系。

【讨论】:

  • 我不能使用附加,因为我在更新方法中使用了这个代码。故事是管理员可以更新任务并使用将参与任务的用户填写输入参与者[]。所以我需要检查它是否存在并删除(或不添加新记录)或者如果它不存在添加它。
【解决方案2】:

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]

【讨论】:

  • 如果在主文档而不是 API 文档中记录,那就太好了!摇滚吧。 +1。
  • 我真的很喜欢带有同步和第二个参数的第二个解决方案。就像我在下面的评论中说的那样,我不能不使用分离。故事是管理员可以将任务分配给用户。他从下拉列表中选择用户(多个),字段是参与者[]。所以...:第 1 步:管理员将任务 A 分配给三个用户(您的方法有效,我们在 DB 中有 3 条记录) 第 2 步:管理员更新任务 A 并添加两个用户(您的方法有效,我们在 DB 中有 5 条记录)第 3 步:管理员更新任务 A 并删除 1 个用户(您的方法失败,我们仍然有 5 个用户而不是 4 个)my update method my code
  • 您可以将关系查询简化为 $this->belongsToMany('User'),如果您使用按字母和单数顺序命名表格(所以 task_user 而不是 user_tasks
  • @Rok 如果你总是传递所有相关用户的数组,那么使用 sync 进行分离,不用担心。当您传递相关模型的单个 id 时,我建议您在想要“为用户添加新任务”或“将用户分配给任务”时使用设置为 false 的第二个参数。
  • @FabioAntunes sync 返回一个包含detachedattachedupdated 列表的数组。 attach 不返回任何内容,但在这两种情况下,如果 db 调用中发生意外情况,您都会收到异常。
【解决方案3】:

这是我关于如何保存和更新所有 Eloquent 关系的笔记。

一对一

您必须在第一个模型上使用 HasOne,在第二个模型上使用 BelongsTo

要在第一个模型(HasOne)上添加记录,请使用保存功能

示例:   $post->comments()->save($comment);

要在第二个模型 (BelongsTo) 上添加记录,请使用 associate 函数

示例:  $user->account()->associate($account);    $user->save();


一对多中:

您必须在第一个模型上使用 HasMany,在第二个模型上使用 BelongsTo

要在第一个表 (HasMany) 上添加记录,请使用 savesaveMany 函数

示例:  $post->comments()->saveMany($comments);

要在第二个模型 (BelongsTo) 上添加记录,请使用 associate 函数

示例:  $user->account()->associate($account);    $user->save();


多对多中:

您必须在第一个模型上使用 BelongsToMany,在第二个模型上使用 BelongsToMany

要在数据透视表上添加记录,请使用 attachsync 函数

  • 这两个函数都接受单个 ID 或 ID 数组

  • 不同之处在于附加检查记录是否已存在于数据透视表中,而同步不存在

例如:$user->roles()->attach($roleId);


多态一对多中:

您必须在主模型上使用 MorphMany,在所有(***able)模型上使用 MorphTo

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

示例:$course->tags()->save($tag);

数据透视表应包含以下列:

。主模型ID

。 (***能)ID

。 (***able) 类型


多态多对多中:

您必须在主模型上使用 MorphBy​​Many,在所有(***able)模型上使用 MorphToMany

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

示例:  $course->tags()->save($tag);

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

数据透视表应包含以下列:

。主模型ID

。 (***能)ID

。 (***able) 类型


有很多通过(快捷方式):

您必须在第一个表上使用 HasManyThrough 并在其他 2 个表上具有正常关系

这不适用于 ManyToMany 关系(有数据透视表)

但是,有一个很好且简单的解决方案。


这是我写的一篇文章,灵感来自这个答案。重要的是检查它:https://hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209

【讨论】:

  • 当他们已经有超过 40 个喜欢的正确答案时,我实际上放置了这个答案,但是是的,我知道这对我有多大用处,很高兴你喜欢它 :)
  • 如何更新一个到可能的关系。你解释了如何添加。你能解释一下更新吗?有没有办法更新像updateMany 这样的记录?谢谢
【解决方案4】:

syncWithoutDetaching([$id_one, $id_two, $id_three]); 是您正在寻找的。实际上它确实做了 [sync with 2nd param false] 做的事情!

【讨论】:

    【解决方案5】:

    已解决:使用 updateOrInsert(array $attributes, array $values = [])

         DB::table('your_pivot_table')->updateOrInsert([
                    'col' => $someValue
                    
    
                ],[
    
                        'otherColumn' => $otherVlaue,
                       
                    ]);
                
    
            }
    

    【讨论】:

      猜你喜欢
      • 2017-07-17
      • 1970-01-01
      • 2018-07-22
      • 1970-01-01
      • 2015-03-05
      • 2015-04-12
      • 2017-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多