web-dev-qa-db-fra.com

Laravel enregistrer/mettre à jour plusieurs relations à plusieurs

Quelqu'un peut-il m'aider sur la façon de sauver plusieurs à plusieurs relations? J'ai des tâches, l'utilisateur peut avoir de nombreuses tâches et la tâche peut avoir de nombreux utilisateurs (plusieurs à plusieurs). Ce que je veux réaliser est que, dans update form, l'administrateur puisse affecter plusieurs utilisateurs à une tâche spécifique. Ceci est fait par HTML plusieurs entrées de sélection 

name="taskParticipants[]"

Le problème ici est que, par le même formulaire (entrée), vous pouvez ajouter/supprimer des utilisateurs, c’est pourquoi je dois utiliser sync () . Peut-être que je devrais commencer par le début mais je ne sais pas par où commencer ... 

Ceci est mon modèle d'utilisateur:

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

Modèle de tâche

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

Ceci est la structure des tables les tâches id | titre | date limite

user_tasks
id|task_id|user_id
57
SuperManSL

tldr; Utilisez sync avec 2nd param false


La relation plusieurs à plusieurs est belongsToMany sur les deux modèles:

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

Pour ajouter une nouvelle relation, utilisez attach ou sync.

La différence entre les deux est la suivante:

1 attach ajoutera une nouvelle ligne au tableau croisé dynamique sans vérifier si elle est déjà présente. C'est bien quand vous avez des données supplémentaires liées à cette relation, par exemple:

User et Exam liés au tableau croisé dynamique attempts: id, user_id, exam_id, score

Je suppose que ce n'est pas ce dont vous avez besoin dans votre 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 d'autre part, supprimera toutes les relations et les redéfinira:

$user->tasks()->getRelatedIds(); // [1,2,3,4,5,6]

$user->tasks()->sync([1,2,3]);
// then
$user->tasks()->getRelatedIds(); // [1,2,3]

ou il va établir de nouvelles relations sans détacher le précédent AND sans ajouter de doublons:

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

Voici mes notes sur la façon de sauvegarder et de mettre à jour toutes les relations Eloquent.

dans One to One:

Vous devez utiliser HasOne sur le premier modèle et BelongsTo sur le deuxième modèle

pour ajouter un enregistrement sur le premier modèle (HasOne), utilisez la fonction save

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

pour ajouter un enregistrement sur le deuxième modèle (BelongsTo), utilisez la fonction associate

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


dans Un à plusieurs:

Vous devez utiliser HasMany sur le premier modèle et BelongsTo sur le deuxième modèle

pour ajouter un enregistrement sur la première table (HasMany), utilisez les fonctions save ou saveMany

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

pour ajouter un enregistrement sur le deuxième modèle (BelongsTo), utilisez la fonction associate

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


dans Plusieurs à plusieurs:

Vous devez utiliser BelongsToMany sur le premier modèle et BelongsToMany sur le deuxième modèle.

pour ajouter des enregistrements sur le tableau croisé dynamique, utilisez les fonctions attach ou sync

  • les deux fonctions acceptent un identifiant unique ou un tableau d'identifiants

  • la différence est de joindre des vérifications si l’enregistrement existe déjà dans le tableau croisé dynamique pendant que la synchronisation n’a pas lieu.

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


dans polymorphe de un à plusieurs:

Vous devez utiliser MorphMany sur le modèle principal et MorphTo sur tous les modèles (*** capables)

pour ajouter des enregistrements sur tous les autres modèles, utilisez la commande save

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

le tableau croisé dynamique doit contenir les colonnes suivantes:

. ID principal du modèle

. (*** capable) ID

. (*** capable) Type


dans polymorphes plusieurs à plusieurs:

Vous devez utiliser MorphByMany sur le modèle principal et MorphToMany sur tous les modèles (*** capables)

pour ajouter des enregistrements sur tous les autres modèles, utilisez save ou saveMany

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

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

le tableau croisé dynamique doit contenir les colonnes suivantes:

. ID principal du modèle

. (*** capable) ID

. (*** capable) Type


dans a beaucoup de traversées (raccourci):

Vous devez utiliser HasManyThrough sur la première table et avoir les relations normales sur les 2 autres tables

cela ne fonctionne pas pour les relations ManyToMany (où il y a un tableau croisé dynamique)

cependant, il existe une solution simple et agréable pour cela.


Voici un article que j'ai écrit, inspiré par cette réponse. Important à vérifier: https://hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209

71
Mahmoud Zalt

La fonction sync efface les relations existantes et donne à votre tableau la liste complète des relations. Vous souhaitez plutôt que attach ajoute des relations sans en supprimer d'autres.

0
ceejayoz