web-dev-qa-db-fra.com

Laravel, sync () - comment synchroniser un tableau et transmettre des champs de pivot supplémentaires?

La documentation officielle Laravel) est présente sur la fonction sync():

$user->roles()->sync( array( 1, 2, 3 ) );

Vous pouvez également associer d'autres valeurs de tableau croisé dynamique aux ID donnés:

$user->roles()->sync( array( 1 => array( 'expires' => true ) ) );

Dans le dernier exemple, une seule ligne pivot est ajoutée. Ce que je ne comprends pas, c'est comment puis-je associer d'autres enregistrements de tableau croisé dynamique s'il y a plus d'une ligne à synchroniser?

Merci d'avance.

51

Afin de sync plusieurs modèles avec des données de pivot personnalisées, vous avez besoin de ceci:

$user->roles()->sync( array( 
    1 => array( 'expires' => true ),
    2 => array( 'expires' => false ),
    ...
));

C'est à dire.

sync( array( 
    related_id => array( 'pivot_field' => value ),
    ...
));

modifier

Répondre au commentaire:

$speakers  = (array) Input::get('speakers'); // related ids
$pivotData = array_fill(0, count($speakers), ['is_speaker' => true]);
$syncData  = array_combine($speakers, $pivotData);

$user->roles()->sync($syncData);
106
Jarek Tkaczyk

Ça marche pour moi

foreach ($photos_array as $photo) {

    //collect all inserted record IDs
    $photo_id_array[$photo->id] = ['type' => 'Offence'];  

}

//Insert into offence_photo table
$offence->photos()->sync($photo_id_array, false);//dont delete old entries = false
12
The Dude

Ajoutez le trait suivant à votre projet et ajoutez-le à votre classe de modèle en tant que trait. Ceci est utile car cela ajoute une fonctionnalité permettant d'utiliser plusieurs pivots. Probablement que quelqu'un peut nettoyer cela un peu et l'améliorer;)

namespace App\Traits;

trait AppTraits
{
    /**
     * Create pivot array from given values
     *
     * @param array $entities
     * @param array $pivots
     * @return array combined $pivots
     */
    public function combinePivot($entities, $pivots = [])
    {
        // Set array
        $pivotArray = [];
        // Loop through all pivot attributes
        foreach ($pivots as $pivot => $value) {
            // Combine them to pivot array
            $pivotArray += [$pivot => $value];
        }
        // Get the total of arrays we need to fill
        $total = count($entities);
        // Make filler array
        $filler = array_fill(0, $total, $pivotArray);
        // Combine and return filler pivot array with data
        return array_combine($entities, $filler);
    }
}

Modèle:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Example extends Model
{
    use Traits\AppTraits;
    // ...
}

Usage:

// Get id's
$entities = [1, 2, 3];
// Create pivots
$pivots = [
    'price' => 634,
    'name'  => 'Example name',
];
// Combine the ids and pivots
$combination = $model->combinePivot($entities, $pivots);
// Sync the combination with the related model / pivot
$model->relation()->sync($combination);
1
Tom van Tilburg

Attacher/détacher

Eloquent fournit également quelques méthodes d'assistance supplémentaires pour rendre le travail avec des modèles associés plus pratique. Par exemple, imaginons qu'un utilisateur puisse avoir plusieurs rôles et qu'un rôle puisse avoir plusieurs utilisateurs. Pour attacher un rôle à un utilisateur en insérant un enregistrement dans la table intermédiaire qui joint les modèles, utilisez la méthode attach:

$user = App\User::find(1);

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

Lorsque vous associez une relation à un modèle, vous pouvez également transmettre un tableau de données supplémentaires à insérer dans la table intermédiaire:

$user->roles()->attach($roleId, ['expires' => $expires]);

Vous pouvez également utiliser Sync si vous souhaitez supprimer d'anciens rôles et ne conserver que les nouveaux que vous attachez maintenant.

$user->roles()->sync([1 => ['expires' => $expires], 2 => ['expires' => $expires]);

Le comportement par défaut peut être modifié en passant un "faux" comme second argument. Cela associera les rôles avec les identifiants 1,2,3 sans affecter les rôles existants.

Dans ce mode, la synchronisation se comporte de la même manière que la méthode attach.

$user->roles()->sync([1 => ['expires' => $expires], 2 => ['expires' => $expires], false);

Référence: https://laravel.com/docs/5.4/eloquent-relationships

1
Miguel Trevino

Il suffit simplement de ajouter votre champs et leurs valeurs aux éléments:

$user->roles()->sync([
   1 => ['F1' => 'F1 Updated']
]);
0
X 47 48 - IR