0

I'm currently using the Revisionable Package v1.28.0 for Laravel v5.4.23 which is a great couple for the most situations.

But now I got a little problem with the revisioning of input arrays. The input element <input name="company_list[]"> is not a big deal but its kind of invisible for the revisionable package. So no changes are written to the database. A dd() of the request shows the content of the input fields.

"company_list" => array:3 [0 => "12", 1 => "10",2 => "2"]

The input array will be synchronized with the User Model.

$user->companies()->sync($request->input('company_list',[]))

Is there a way to get the changes and translate the ids to the specific names?

Thanks a lot!

alessandrio
  • 4,282
  • 2
  • 29
  • 40
Texx
  • 23
  • 4
  • Syncing should set the new list. So if you have a name field in the companies table then you could do `$user->companies()->pluck('name')` to get the new company name list. – Sandeesh May 29 '17 at 14:16

1 Answers1

0

Currently revisionable isn't supporting Many To Many relations. But I solved this problem with the following codes:

/**
 * Make revision and sync for many to many relations
 *
 * @param string $relation
 * @param array $list
 * @return array
 */
public function doSync($relation, $list)
{
    $rel = $this->{$relation}();
    $old = $rel->pluck('id')->implode(',');
    $rel->sync($list);
    $new = $rel->pluck('id')->implode(',');
    storePivotRevision($this, $relation, $old, $new);
}

/**
 * Store revision for pivot tables
 *
 * @param string $relation
 * @param string $old
 * @param string $new
 * @return null
 */
function storePivotRevision($relation, $old, $new)
{
    if ($old == $new) {
        return;
    }
    DB::table('revisions')->insert([
        'revisionable_type' => get_class($this),
        'revisionable_id' => $model->id,
        'user_id' => auth()->check() ? auth()->user()->id : null,
        'key' => "{$relation}_pivot",
        'old_value' => $old,
        'new_value' => $new,
        'created_at' => now(),
        'updated_at' => now(),
    ]);
}

Now instead of
$user->roles()->sync([1, 2, 3, ...]);

you can use
$user->doSync('roles', [1, 2, 3, ...]);

The code is written generally for all models (not specified to one), so you can put them inside a trait and call it like this:

$model->doSync('many_to_many_relation', $listArray);

Hope this helps :)

Khalil Laleh
  • 1,168
  • 10
  • 19