web-dev-qa-db-ja.com

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));
        }
    }
}

これはテーブルの構造ですタスクid | title | deadline

user_tasks
id|task_id|user_id
69
SuperManSL

tldr;syncを2番目のパラメーターで使用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');
}

新しい関係を追加するには、attachまたはsyncを使用します。

2つの違いは次のとおりです。

1attachは、ピボットテーブルに新しい行が追加されますが、既に存在するかどうかを確認しません。そのリレーションに追加のデータがリンクされていると便利です。たとえば:

UserおよびExamピボットテーブルとリンク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]

2sync一方、すべてのリレーションを削除して、それらを新たに設定します。

$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]
161
Jarek Tkaczyk

すべてのEloquentリレーションシップを保存および更新する方法に関するメモを次に示します。

inOne to One

最初のモデルではHasOneを使用し、2番目のモデルではBelongsToを使用する必要があります型

最初のモデルにレコードを追加するには(HasOnesave関数を使用します

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

2番目のモデルにレコードを追加するには(BelongsToassociate関数を使用します

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


inOne to Many

最初のモデルではHasManyを使用し、2番目のモデルではBelongsToを使用する必要があります型

最初のテーブルにレコードを追加するには(HasMany)(save)またはsaveMany関数

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

2番目のモデルにレコードを追加するには(BelongsToassociate関数を使用します

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


in多対多

最初のモデルではBelongsToManyを使用し、2番目のモデルではBelongsToManyを使用する必要があります型

ピボットテーブルにレコードを追加するには、attachまたはsync関数を使用します

  • 両方の関数は、単一のIDまたはIDの配列を受け入れます

  • 違いは、レコードがピボットテーブルに既に存在するかどうかをアタッチチェックし、同期はしないことです

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


inPolymorphic One to Many

メインモデルではMorphManyを使用し、すべてのモデルではMorphToを使用する必要があります(***可能)モデル

他のすべてのモデルにレコードを追加するには、saveを使用します

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

ピボットテーブルには次の列が必要です。

。メインモデルID

。 (***可能)ID

。 (***可能)タイプ


in多相多対多

メインモデルではMorphBy​​Manyを使用し、すべてのモデルではMorphToManyを使用する必要があります(***可能)モデル

他のすべてのモデルにレコードを追加するには、saveまたはsaveManyを使用します

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

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

ピボットテーブルには次の列が必要です。

。メインモデルID

。 (***可能)ID

。 (***可能)タイプ


inHas Many Through(ショートカット):

最初のテーブルでHasManyThroughを使用し、他の2つのテーブルで通常の関係を持つ必要があります

これはManyToMany関係(ピボットテーブルがある場合)では機能しません

ただし、そのための素敵で簡単な解決策があります。


この答えに触発されて私が書いた記事はこちらです。確認することが重要です: https://hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209

84
Mahmoud Zalt

sync関数は、既存の関係を消去し、配列を関係のリスト全体にします。代わりにattachを使用して、他を削除せずに関係を追加します。

0
ceejayoz