Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

theferrett's avatar

Storing A Snapshot Of A Model Entry?

Is there a package that stores and retrieves a copy of a model entry's values at a given, triggered time?

Our use case: We have a workflow where many employees can save changes to a given model. What we want is to save a copy of the model as it was when an employee marked it as ready it to hand it onto the next employee, so we can load up a record and say "This is how it was when Bethany got it."

We could use an audit trail, but the users may make many changes to a model before they hand it off to the next employee, and it'd get computationally expensive to go through each field and replay the values until we got to an arbitrary point in time.

Ideally, we'd have some turnkey solution where we say "Okay, Bethany's got it, make a snapshot for record #123" and that would be stored to be retrieved at some later date. Or if there's an easy solution that I'm missing in Laravel, that too would be great!

But this is juuuuuuust edge case enough that maybe someone's solved this.

Thanks, T.F.

0 likes
6 replies
MohamedTammam's avatar

I didn't face that use case before, but here's how I would do it.

  1. Create a database table similar to the model that I want to save with an extra saved_at timestamp field. But solution will work if I have only one model.

  2. Store the model values as a JSON with morph relationship in a separated table. But then we need to keep converting it to a model again after retrieving the JSON data.

  3. Duplicate the row inside the same table with a parent_id marking the origin record, and when we need to retirve the most updated one we use saved_at to get last saved item.

Just thinking with you loudly.

theferrett's avatar

@MohamedTammam #2 is interesting. Is it possible to convert a JSON into an Eloquent model? I have not seen that before.

sub1ms's avatar

There are several options to achieve this. One approach that I would recommend is using a database trigger. Which doesn't require any direct application config/programming by itself to capture changes.

  • This is great for sensitive data where version control is a must
  • Multiple applications or services may interface with a single database
  • Doesn't task app servers with excess load
  • Fairly simple to implement (requires some knowledge of SQL)
  1. Duplicate the table and append/prepend an identifier to the table name that indicates changes/history. This can be something like "customer_jobs_changelog"
  2. Setup a table trigger on "customer_jobs" on before update. In this trigger, you can quantify which fields it should look at to detect a change that it should log, perhaps when assignee_id is changed (handed off). Likewise, you don't have to define fields if you want to track all changes.

An example that you can use and modify:

CREATE TABLE `customer_jobs` (
 `customer_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `assignee_id` int(11) DEFAULT NULL,
 `other_properties` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`customer_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE DEFINER=`root`@`localhost` TRIGGER `ChangeLog` AFTER UPDATE ON `customer_jobs` FOR EACH ROW BEGIN
SET @new_value = NEW.assignee_id;
SET @old_value = OLD.assignee_id;
IF (@new_value != @old_value) THEN INSERT INTO customer_jobs_cangelog (`customer_id`, `assignee_id`, `other_properties`) VALUES (NEW.customer_id, NEW.assignee_id, NEW.other_properties); END IF;
END

Another approach on an application level you can take is using Elquoent Events. https://laravel.com/docs/9.x/eloquent#events When an update on the model occurs, you can include some logic that compares the new and previous value of a particular field(s) and decide whether or not a "snapshot" model should be saved based on your criteria.

theferrett's avatar

@sub1ms The database trigger is a very good idea, with the issue that our department doesn't generally use triggers and hence I suspect they'd be confused by the magic if I wasn't there to explain it to them. (I've used triggers in the past, and it's provided Mysteries.)

The events I haven't used much in Eloquent models, and that seems a decent way to go.

Please or to participate in this conversation.