Una nuova funzionalità di Laravel 5.5 sarà il supporto per il pivot table casts durante l’inserimento o l’update dal model di una tabella intermedia.

Adsso il $cast che viene settato nel model tradizionale funziona in entrambe le direzioni; ogni model che estende la classe Eloquent\Model cerca la proprietà $casts e converte gli attributi specificati in data type in lettura e scrittura. Per esempio, dalla documentazione:

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
    * The attributes that should be cast to native types.
    * @var array
    */
    protected $casts = [
        'is_admin' => 'boolean',
    ];
}

In Laravel 5.4, Taylor ha aggiunto la possibilità di definire una proprietà $cast anche su un model Pivot, ma viene applicata solo in lettura, nessuna conversione viene effettuata in scrittura o aggiornamento di un attributo.

Per esempio, supponiamo che tu abbia un model Runner e un model Race. Un Runner può avere molti Race e Race può avere molti Runner. Chiamiamo il nostro model pivot RaceRunner, che include un array splits con un numero variabile di tempi per giro (a seconda della lunghezza della gara, e salvato in secondi) oltre i campi obbligatori race_id e runner_id.

L’array splits è serializzato in json nella tabella race_runner, così se hai definito gli split come un array nell’attributo $cast del model RaceRunner. facendone il dump otterrai:

dd( $runner->pivot->splits );

// Example:
[
    'Lap 1' => 150,
    'Lap 2' => 163,
    'Lap 3' => 146
]

Ma in update o create devi fare la conversione da manualmente:

// Cast first...
$splits = $splits->toJson();

// ...then attach:
$runner->races()->attach($raceId, ['splits' => $splits]);

Adesso con Laravel 5.5, la poprietà $cast di Eloquent\Model e quella di Eloquent\Pivot si comportano allo stesso modo. Laravel “rispetterà” i tuoi $casts in entrambi, sia in lettura, inserimento o update. Questo rende i metodi attach, sync e save disponibili ai model pivot. Applicando questo principio all’esempio precedente renderà il codice // Cast first… non più necessario.