Blagoh
Blagoh

Reputation: 1235

Figure what fields `save()` acted on if any (detecting changes)

Doing ->save() and ->update() only updates when changes made, I think, is this true?

Here's the relevant part of code in Illuminate\Database\Eloquent\Model@performUpdate:

protected function performUpdate(Builder $query, array $options = [])
{
    $dirty = $this->getDirty();

    if (count($dirty) > 0)
    {
        // runs update query
    }

    return true;
}

I typically update like this:

public function update(Requests\UpdatePetRequest $request, Pet $pet)
{
    $pet->update($request->all());
    return $pet;
}

I want to figure from ->save and from ->update if what field names were updated? Along with what was the old value and the new value.

I currently manually do this like this:

public function update(Requests\UpdatePetRequest $request, Pet $pet)
{
    $changes = [];
    if ($request->exists('name') && $request->name != $pet->name) {
        $changes['name'] = array([
            'old' => $pet->name,
            'new' => $request->name
        ]);
    }
    if ($request->exists('avatar') && $request->avatar != $pet->avatar) {
        $changes['avatar'] = array([
            'old' => $pet->avatar,
            'new' => $request->avatar
        ]);
    }

    if (!count($changes)) {
        return response()->json(['error'=>'No properties changed'], 422);
    }

    $pet->update($request->all());

    $body = json_encode($changes);

    $message = new Message(['body' => $body, 'kind' => 'PET_UPDATE']);
}

Is there an automated way to do this?

Upvotes: 1

Views: 26

Answers (1)

Alexey Mezenin
Alexey Mezenin

Reputation: 163898

You can't do that with update(), but you can use getDirty() before save():

$model = Model::find($id);
$model->fill($request->all());
$cahnges = $model->getDirty();
$model->save();

getDirty() will return you an array with changed columns only, for example:

['name' => 'New Name', 'address' => 'New Street, 12']

Upvotes: 1

Related Questions