Laravel, sync() – hoe synchroniseer je een array en geef je ook extra draaivelden door?

Officiële Laravel-documentatie heeft dit op sync()-functie:

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

U kunt ook andere draaitabelwaarden koppelen aan de opgegeven ID’s:

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

In het laatste voorbeeld wordt slechts één enkele rij met spil toegevoegd. Wat ik niet begrijp, is hoe ik andere draaitabelrecords kan koppelen als er meer dan één rij moet worden gesynchroniseerd?

Bij voorbaat dank.


Antwoord 1, autoriteit 100%

Als je meerdere modellen wilt syncsamen met aangepaste spilgegevens, heb je dit nodig:

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

Dwz.

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

bewerken

De opmerking beantwoorden:

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

Antwoord 2, autoriteit 32%

Dit werkt voor mij

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

Antwoord 3, autoriteit 4%

Er is nu een ->syncWithPivotValues($ids, $pivotValues)methode beschikbaar als u dezelfde spilwaarde wilt instellen voor alle gesynchroniseerde items.

Voorbeeld uit het document:

$user->roles()->syncWithPivotValues([1, 2, 3], ['active' => true]);

Antwoord 4, autoriteit 2%

Bevestigen/losmaken

Eloquent biedt ook enkele aanvullende hulpmethoden om het werken met verwante modellen gemakkelijker te maken. Laten we ons bijvoorbeeld voorstellen dat een gebruiker veel rollen kan hebben en een rol veel gebruikers. Om een ​​rol aan een gebruiker te koppelen door een record in te voegen in de tussentabel die de modellen verbindt, gebruikt u de methode attach:

$user = App\User::find(1);
$user->roles()->attach($roleId);

Als u een relatie aan een model koppelt, kunt u ook een reeks aanvullende gegevens doorgeven om in de tussentabel in te voegen:

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

Je kunt Sync ook gebruiken als je oude rollen wilt verwijderen en alleen wilt behouden
de nieuwe die u nu bijvoegt

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

Het standaardgedrag kan worden gewijzigd door een ‘false’ als tweede door te geven
argument.
Dit zal de rollen met ids 1,2,3 koppelen zonder de bestaande te beïnvloeden
rollen.

In deze modus gedraagt ​​synchronisatie zich vergelijkbaar met de methode bijvoegen.

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

Referentie:
https://laravel.com/docs/5.4/eloquent-relationships


Antwoord 5

Voeg de volgende eigenschap toe aan uw project en voeg deze toe aan uw modelklasse als een eigenschap. Dit is handig, omdat dit functionaliteit toevoegt om meerdere pivots te gebruiken.
Waarschijnlijk kan iemand dit een beetje opruimen en verbeteren 😉

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

Model:

namespace App;
use Illuminate\Database\Eloquent\Model;
class Example extends Model
{
    use Traits\AppTraits;
    // ...
}

Gebruik:

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

Antwoord 6

Gewoon voeguw veldenen hun waardentoe aan de elementen:

$user->roles()->sync([
   1 => ['F1' => 'F1 Updated']
]);

Antwoord 7

$data = array();
foreach ($request->planes as $plan) {
 $data_plan = array($plan => array('dia' => $request->dia[$plan] ) );                
 array_push($data,$data_plan);    
}
$user->planes()->sync($data);

Antwoord 8

Ik plaats dit hier voor het geval ik het later vergeet en Google het opnieuw.

In mijn geval wilde ik dat de extra kolom dezelfde gegevens had voor elke rij

Waar $syncData een reeks ID’s is:

$syncData = array_map(fn($locationSysid) => ['other_column' => 'foo'], array_flip($syncData));

of zonder pijl

$syncData = array_map(function($locationSysid) {
      return ['ENTITY' => 'dbo.Cli_Core'];
   }, array_flip($syncData));

(array_flip betekent dat we de ID’s gebruiken als de index voor de array)

Other episodes