Laravel salvare / aggiornare le relazioni molti a molti

Qualcuno mi può aiutare su come salvare le relazioni molti a molti? Ho compiti, l’utente può avere molti compiti e attività può avere molti utenti (molti a molti), Quello che voglio ottenere è che in modulo di aggiornamento l’amministratore può assegnare a più utenti di un compito specifico. Questo viene fatto attraverso html select multiple input

name="taskParticipants[]"

La cattura è che attraverso la stessa forma (input) è possibile aggiungere/rimuovere utenti, che è il motivo per cui devo usare il sync().
Forse dovrei cominciare dall’inizio, ma non so da dove cominciare…

Questo è il mio modello di Utente:

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

Modello di attività

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

Questa è la struttura delle tabelle
attività
id|titolo|scadenza

user_tasks
id|task_id|user_id
  • Ho aggiornato il mio codice. link
  • $workers = Input::get('taskParticipants'); $task->taskParticipants()->sync($workers); e tutto ciò che è necessario, come lungo come si passa da che forma tutti gli utenti, assegnato per l’attività.
  • Grazie, era magico.
InformationsquelleAutor SuperManSL | 2014-07-11



3 Replies
  1. 161

    tldr; Utilizzare sync con la 2 ° param false


    Molti-a-molti rapporto è belongsToMany su entrambi i modelli:

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

    Per aggiungere un nuovo rapporto uso attach o sync.

    Differenza tra i due è:

    1 attach sarà aggiungere una nuova riga nella tabella pivot senza controllare se c’è già. E ‘ bello quando si dispone di ulteriori dati legata a quella relazione, per esempio:

    User e Exam collegato con tabella pivot attempts: id, user_id, exam_id, score

    Suppongo che questo non è ciò di cui avete bisogno nella vostra situazione:

    $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 invece, verrà rimuovere tutte le relazioni e di nuovo:

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

    o di installazione di nuovi rapporti senza staccare precedente E senza l’aggiunta di duplicati:

    $user->tasks()->sync([5,6,7,8], false); //2nd param = detach
    //then
    $user->tasks()->getRelatedIds(); //[1,2,3,4,5,6,7,8]
    • Sarebbe bello se questo è stato documentato nei principali documenti piuttosto che le API docs! Rock. +1.
    • Mi piace molto la seconda soluzione con sync e 2 ° parametro. Come ho detto nel commento qui sotto, non mi posso permettere di non utilizzare staccare. La storia è che l’amministratore può assegnare attività per gli utenti. Egli selezionare gli utenti dall’elenco a discesa (più di uno), campo partecipanti[]. Così… : Passo 1: admin assegna Un compito a tre utenti (il tuo metodo funziona, ci sono 3 i record nel DB) Passo 2: admin aggiornamenti compito e aggiunge due utenti (il tuo metodo funziona, ci sono 5 record nel DB) Passo 3: admin aggiornamenti attività e rimuove 1 utente (il tuo metodo non riesce, abbiamo ancora 5 gli utenti, invece di 4) il mio metodo di aggiornamento il mio codice
    • È possibile semplificare la tua query di relazione a soli $this->belongsToMany('User') se si utilizza il nome della tabella in ordine alfabetico e singolare (modo task_user invece di user_tasks)
    • se avete sempre passare un array di tutti i relativi utenti, quindi utilizzare sync con distacco, senza preoccupazioni. Io suggerisco di usare 2 ° param impostata su false ogni volta che vuoi “aggiungi nuova attività per un utente’ o ‘utente di assegnare un task’, quando si passa singolo id del relativo modello.
    • Ho aggiornato la mia domanda, si prega di dare un’occhiata
    • Esiste per ‘oneToMany’ rapporto?
    • simile in che modo?
    • qualcosa come ‘sync’
    • solo ->relation()->saveMany(array $models)
    • Come fai a sapere se la sincronizzazione o collegamento è stato eseguito correttamente?
    • restituisce un array con detached, attached e updated liste. attach non restituisce nulla, ma in entrambi i casi, si dovrebbe ottenere una eccezione se qualcosa di inaspettato è accaduto nel db chiamate.
    • fresco, grazie per il suggerimento.

  2. 84

    Ecco i miei appunti su come salvare e aggiornamento su tutti i Eloquente relazioni.

    in Uno per Uno:

    È necessario utilizzare HasOne il primo modello e Appartiene il secondo modello

    per aggiungere un record al primo modello (HasOne) utilizzare il salvare funzione

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

    per aggiungere registrare sul secondo modello (Appartiene) utilizzare il associare funzione

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


    in Uno a Molti:

    È necessario utilizzare HasMany il primo modello e Appartiene il secondo modello

    per aggiungere record della prima tabella (HasMany) utilizzare il salvare o saveMany funzioni

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

    per aggiungere registrare sul secondo modello (Appartiene) utilizzare il associare funzione

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


    in molti a Molti:

    Devi usare BelongsToMany il primo modello e BelongsToMany il secondo modello

    per aggiungere record in una tabella pivot utilizzare allegare o sync funzioni

    • sia funzioni accetta singolo ID o array di ID 

    • la differenza è collegare controlla se il record esiste già nella tabella pivot, mentre la sincronizzazione non

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


    in Polimorfici Uno a Molti:

    Hai usare MorphMany sul modello principale e MorphTo su tutte le***e ‘ in grado) modelli

    per aggiungere record su tutti gli altri modelli di utilizzare il salvare

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

    tabella pivot deve avere i seguenti colonne:

    . principale ID modello

    . (***e ‘ in grado) ID

    . (***e ‘ in grado) di Tipo


    in Polimorfici molti a Molti:

    Hai usare MorphByMany sul modello principale e MorphToMany su tutte le***e ‘ in grado) modelli

    per aggiungere record su tutti gli altri modelli di utilizzare il salvare o saveMany

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

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

    tabella pivot deve avere i seguenti colonne:

    . principale ID modello

    . (***e ‘ in grado) ID

    . (***e ‘ in grado) di Tipo


    in Ha Molti Attraverso (scelta rapida):

    È necessario utilizzare HasManyThrough nella prima tabella e avere normali relazioni con gli altri 2 tavoli

    questo non funziona per ManyToMany relazioni (dove c’è una tabella pivot)

    tuttavia c’è una bella soluzione facile e solo per quella.


    Ecco un articolo che ho scritto, ispirato da questa risposta. Importante controllare: https://hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209

    • questo dovrebbe avere più di upvote
    • In realtà ho messo questa risposta quando hanno già avuto più di 40 mi piace sulla risposta corretta, ma sì, lo so come questo è utile per me, sono contento che ti piaccia 🙂
    • Vorrei sapere che sei un salvatore
    • questa è una grande risposta.
    • Molto utile, più di upvotes ^
    • come aggiornare una a maggio relazione. u spiegato come aggiungere . potrebbe per favore spiegare l’aggiornamento troppo? c’è un metodo per aggiornare i record come updateMany qualcosa di simile? grazie

  3. 0

    Il sync funzione cancella l’uscita relazioni e rende il vostro array l’intero elenco dei rapporti. Vuoi attach invece di aggiungere relazioni senza togliere gli altri.

    • Non posso usare allegare perché sto usando questo codice all’interno del metodo di aggiornamento. La storia è che un admin può attività di aggiornamento e di riempimento in ingresso dei partecipanti[] con gli utenti che potranno partecipare alle attività. Quindi ho bisogno di controllare se esiste ed eliminare (o di non aggiungere un nuovo record) o, se non esiste, aggiungere.

Lascia un commento