Search code examples
laravelrevisionable

How do I get just the most recent set of changes in the revisionable package?


Currently I have the revisionable trait correctly storing and fetching the history of a model goes through change.

Each update to a model creates a record per field that was changed.

Is it possible to group those records by change?

Example Time:

Round 1

$model = MyModel::find(1);
$model->a = 5;
$model->b = 6;
$model->save();

This results in the following entries

+----------+--------+-----+-----------+-----------+--------------+
| rev_type | rev_id | key | old_value | new_value |  created_at  |
+----------+--------+-----+-----------+-----------+--------------+
| MyModel  |      1 | a   |         0 |         5 | [first date] |
| MyModel  |      1 | b   |         0 |         6 | [first date] |
+----------+--------+-----+-----------+-----------+--------------+

Round 2

$model = MyModel::find(1);
$model->a = 555;
$model->b = 666;
$model->save();

This results in the following entries

+----------+--------+-----+-----------+-----------+---------------+
| rev_type | rev_id | key | old_value | new_value |  created_at   |
+----------+--------+-----+-----------+-----------+---------------+
| MyModel  |      1 | a   |         0 |         5 | [first date]  |
| MyModel  |      1 | b   |         0 |         6 | [first date]  |
| MyModel  |      1 | a   |         5 |       555 | [second date] |
| MyModel  |      1 | b   |         6 |       666 | [second date] |
+----------+--------+-----+-----------+-----------+---------------+

In this case, I want to grab just records 3 and 4.

Initial thinking includes fetching and grouping by the created_at date, then simply fetching the last group (the most recent date). However I don't know if there is a guarantee that the dates will be identical.

Is there a way to group by update when retrieving the history from revisionable?

EDIT

Upon deeper investigation - revisionable created_at date is using the built in ->withTimestamps() trait. For each insert in a batch insert (like the one revisionable uses), a fresh timestamp is grabbed as a Carbon date, this means (from my understanding) that a batch insert could have different created_at dates.


Solution

  • There are two possibilities:

    First one: You search for the latest entry

    $latestDate = Changes::orderBy('created_at' 'desc')->first()->created_at;
    $latestEntries = Changes::where('created_at', $latestDate)->get();
    

    But it's not 100% good because when the time changes between to inserts you get wrong results.

    So better use this way:

    Add another column where you count the changes. Everytime you make a change (in your case you add 2 new lines), you increase the integer by one. So you know what changes where made first, then second and so on.

    //get the latest changes
    $latestChange = Changes::orderBy('created_at' 'desc')->first()->saveId;
    $latestEntries = Changes::where('savedId', $latestChange)->get();