Laravel enregistrer / mettre à jour plusieurs à plusieurs relation

Quelqu'un peut-il m'aider sur la façon de sauver plusieurs à plusieurs relation? J'ai des tâches, l'utilisateur peut avoir beaucoup de tâches et la tâche peut avoir beaucoup d'utilisateurs (beaucoup à beaucoup), ce que je veux réaliser est que dans update form admin peut assigner plusieurs utilisateurs à une tâche spécifique. Cela se fait via html Multiple Select input

name="taskParticipants[]"

Le hic 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...

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

C'est la structure des tableaux tâche id / titre / date limite

user_tasks
id|task_id|user_id
50
demandé sur SuperManSL 2014-07-11 20:42:41

3 réponses

tldr; Utiliser sync avec la 2ème param false


Plusieurs-à-Plusieurs relation 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 un nouveau lien utiliser attach ou sync.

La différence entre les deux est:

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

User et Exam lié avec pivot tableau 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 mettra à nouveau en place:

$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 configurer de nouvelles relations sans détacher précédent et 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]
122
répondu Jarek Tkaczyk 2015-06-19 07:36:16

Voici mes notes sur la façon d'enregistrer et de mettre à jour toutes les relations éloquentes.

Dans un à Un:

, Vous devez utiliser HasOne sur le premier modèle et BelongsTo sur le second modèle

Pour ajouter un enregistrement sur le premier modèle (HasOne) utiliser le enregistrer function

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

Pour ajouter un enregistrement sur le second modèle (BelongsTo) utiliser le associer function

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


Dans "Un à Plusieurs" :

, Vous devez utiliser HasMany sur le premier modèle et BelongsTo sur le second modèle

Pour ajouter un enregistrement sur la première table (HasMany) utiliser le enregistrer ou saveMany fonctions de

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

Pour ajouter un enregistrement sur le second modèle (BelongsTo) utiliser le associer function

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


Dans beaucoup à Beaucoup :

, Vous devez utiliser BelongsToMany sur le premier modèle et BelongsToMany sur le second modèle

Pour ajouter des enregistrements sur le pivot de l'utilisation de la table attacher ou synchronisation fonctions de

  • Les deux fonctions acceptent un seul ID ou un tableau d'ID

  • La différence est attach vérifie si l'enregistrement existe déjà sur le tableau croisé dynamique alors que sync ne le fait pas

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


Dans polymorphique un à plusieurs:

, Vous devez utiliser MorphMany sur le modèle principal et MorphTo sur toutes les (***mesure de le faire) les modèles

Pour ajouter des enregistrements sur tous les autres modèles de la enregistrer

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

Le tableau croisé dynamique doit avoir les colonnes suivantes:

. modèle principal ID

. (***mesure) ID

. (***capable) Type


Dans Polymorphe de Nombreux de Nombreux:

Vous devez utilisez MorphByMany sur le modèle principal et MorphToMany sur tous les modèles (***able)

Pour ajouter des enregistrements sur tous les autres modèles de la enregistrer ou saveMany

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

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

Le tableau croisé dynamique doit avoir les colonnes suivantes:

. modèle principal ID

. (***mesure) ID

. (***capable) Type


Dans a beaucoup à travers (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 y a une solution agréable et facile juste pour cela.


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

57
répondu Mahmoud Zalt 2017-12-05 13:09:28

La fonction sync efface les relations sortantes et fait de votre tableau la liste complète des relations. Vous voulez que attach ajoute des relations sans en supprimer d'autres.

0
répondu ceejayoz 2014-07-11 16:51:49