I'd like to build a history feature into my application such that when a user updates one of my objects / records, I track that as an event that also stores the original values on the object and the updated values on the object.
I'd like to be able to come back around to look at that using the objects themselves, so I think that means I would need to store the data in a way I can read it back.
I'd like to do this without too much variance from the way Laravel and Eloquent manage the Model - Table relationship, so I think that precludes doing something like storing multiple copies of the record in the model's table.
I thought about creating a history table of sorts and storing the pre-edit and post-edit versions of the Eloquent model object as JSON (or something else?) in two different fields, creating a new record each time there was an update. I got about that far and thought it would be cool to do that but I couldn't figure out how to reconstitute an Eloquent Model object from JSON sitting in a record in a table.
What techniques have you guys used to do this with Laravel?
Use a second database, laravel can have multiple database connections. I do accounting that way, I have a backup table for older ledger entries. That json thing nah.
This is easily accomplished using a database trigger. Laravel doesn't have it built in, but you can easily create a trigger using raw sql, and then have a model to work with the "history" table. Triggers work at the database level and don't involve any php at all. You basically tell it "when this table is updated, copy it's data to this other table". It's really fast since it's internal and happens automatically behind the scenes at the database level.
You can have triggers for INSERT, as well as UPDATE functions. You can have conditionals, etc, like "if x field changes on an update, then copy to history table"
I use this for tracking changes in real estate data for properties, so anytime a field on a property gets updated, it creates an entry in the history table so I can track all changes to properties over time. You just need to create a regular model to retrieve the data from the table and have a one-to-many relationship to the history table (one property can have many histories). The "listings" table holds the current listing data, and the "listing_history" table contains all previously changed data.
@thc1967 I have a simple pet database I use just for test data, here is what a simple trigger looks like
DELIMITER $$
DROP TRIGGER /*!50032 IF EXISTS */ `pbackdate`.`au_petname`$$
CREATE
/*!50017 DEFINER = 'root'@'localhost' */
TRIGGER `pbackdate`.`au_petname` AFTER UPDATE ON `pbackdate`.`pets`
FOR EACH ROW BEGIN
INSERT INTO `nameback` SET `petnamebak` = OLD.petname;
END;
$$
DELIMITER ;
Just quick example, change a name, and old name is backed up. But remember, that backed up data grows fast with triggers, every edit. Have to figure out a purge technique.
I would prefer to manage the record as a whole instead of creating the equivalent of a row per field. If I have new and old together, I can show them side-by-side and do cool things like filter to only populated values or only changed values.
I don't think I'll be high enough volume that I need to worry about purging or storage. The system that I'm replacing has been in place for over 15 years, it tracks history as 1 record per 1 field change, and it has under 500,000 records in its history table.
So let's change the question...
If I have a JSON representation of an Eloquent model inside a field in a table, how would I reconstitute that into the right Eloquent model object in PHP / Laravel? I feel like I should be looking into how polymorphic relations work...