12
Mar '18

Serialising Records With Relations in Laravel

Bit of a follow-on here from my post on record versioning. Versioning a record is all well and good, but often you would like to version the reccord’s relations too in order to make the record meaningful, provide context, provide metadata etc.

In the code below, the archive function on the parent model is triggered to create the archive (versioned) record. Note that I have added the with(‘notes’) call, which will add all related records from the ‘notes’ relation into the resulting array. As such this relation has been serialiasied with the parent record.

When the archive (versioned) record is deserialised we will then find that the ‘notes’ are attached to the copy of the parent model, but as simple arrays rather than objects. The custom ‘hydrateArchive’ function simply takes these arrays and turns them back into real models.

Parent Model

/**
 * Archive
 * @return \App\Model\Archive
 */
public function archive() {
    return $this->archives()->create([
        'data' => serialize($this->with('notes')->find($this->id)->toArray())
    ]);
}

/**
 * Custom archive hydrate
 *
 * @return \App\Model\Base
 */
public function hydrateArchive() {
    if(!$this->notes)
        return $this;

    $this->notes = collect($this->notes)->map(function ($data) {
        return new \App\Model\Note($data);
    });

    return $this;
}

Archive Record

/**
 * Deserialise
 * @return \App\Model\Base
 */
public function deserialise() {
    $deserialised = with(new $this->parent_type)->newFromBuilder(unserialize($this->data));
    return $deserialised->hydrateArchive();
}

Leave a Reply