[php] Laravel, sync() - how to sync an array and also pass additional pivot fields?

Official Laravel documentation has this on sync() function:

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

You may also associate other pivot table values with the given IDs:

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

In the latter example only a single pivot row is being added. What I don't understand is how can I associate other pivot table records if there are more than one rows to be synced?

Thanks in advance.

This question is related to php laravel pivot eloquent sync

The answer is


Putting this here in case I forget it later and Google it again.

In my case I wanted the extra column to have the same data for each row

Where $syncData is an array of IDs:

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

or without arrow

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

(array_flip means we're using the IDs as the index for the array)


In order to sync multiple models along with custom pivot data, you need this:

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

Ie.

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

edit

Answering the comment:

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

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

Add following trait to your project and append it to your model class as a trait. This is helpful, because this adds functionality to use multiple pivots. Probably someone can clean this up a little and improve on it ;)

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;
    // ...
}

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

Attaching / Detaching

Eloquent also provides a few additional helper methods to make working with related models more convenient. For example, let's imagine a user can have many roles and a role can have many users. To attach a role to a user by inserting a record in the intermediate table that joins the models, use the attach method:

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

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

When attaching a relationship to a model, you may also pass an array of additional data to be inserted into the intermediate table:

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

You can also use Sync if you want to remove old roles and only keep the new ones you are attaching now

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

The default behaviour can be changed by passing a 'false' as a second argument. This will attach the roles with ids 1,2,3 without affecting the existing roles.

In this mode sync behaves similar to the attach method.

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

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


Simply just append your fields and their values to the elements:

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

Examples related to php

I am receiving warning in Facebook Application using PHP SDK Pass PDO prepared statement to variables Parse error: syntax error, unexpected [ Preg_match backtrack error Removing "http://" from a string How do I hide the PHP explode delimiter from submitted form results? Problems with installation of Google App Engine SDK for php in OS X Laravel 4 with Sentry 2 add user to a group on Registration php & mysql query not echoing in html with tags? How do I show a message in the foreach loop?

Examples related to laravel

Parameter binding on left joins with array in Laravel Query Builder Laravel 4 with Sentry 2 add user to a group on Registration Target class controller does not exist - Laravel 8 Visual Studio Code PHP Intelephense Keep Showing Not Necessary Error The POST method is not supported for this route. Supported methods: GET, HEAD. Laravel How to fix 'Unchecked runtime.lastError: The message port closed before a response was received' chrome issue? Post request in Laravel - Error - 419 Sorry, your session/ 419 your page has expired Expected response code 250 but got code "530", with message "530 5.7.1 Authentication required How can I run specific migration in laravel Laravel 5 show ErrorException file_put_contents failed to open stream: No such file or directory

Examples related to pivot

Laravel, sync() - how to sync an array and also pass additional pivot fields? Construct pandas DataFrame from list of tuples of (row,col,values) How to convert Rows to Columns in Oracle? TSQL PIVOT MULTIPLE COLUMNS Convert Rows to columns using 'Pivot' in SQL Server Efficiently convert rows to columns in sql server MySQL - sum column value(s) based on row from the same table SQL Server Pivot Table with multiple column aggregates Simple way to transpose columns and rows in SQL? MySQL pivot table query with dynamic columns

Examples related to eloquent

Eloquent: find() and where() usage laravel How to select specific columns in laravel eloquent Laravel Eloquent where field is X or null Laravel Eloquent limit and offset laravel collection to array Eloquent get only one column as an array Laravel 5.2 - Use a String as a Custom Primary Key for Eloquent Table becomes 0 Laravel 5.2 - pluck() method returns array Eloquent ORM laravel 5 Get Array of ids eloquent laravel: How to get a row count from a ->get()

Examples related to sync

Android Studio how to run gradle sync manually? Laravel, sync() - how to sync an array and also pass additional pivot fields? node.js execute system command synchronously Two way sync with rsync