mpociot / versionable

Laravel Model versioning made easy
MIT License
765 stars 101 forks source link

Model with existing record but no version does not create a version on save() #94

Open JurjenRoels opened 2 years ago

JurjenRoels commented 2 years ago

Hi,

I have a database with existing records and we add the VersionableTrait.

I would expect to get a version if we save an existing record?

However I get this with tinker:

$z->versions => Illuminate\Database\Eloquent\Collection {#4160 all: [], }

$z->save() => true

$z->versions => Illuminate\Database\Eloquent\Collection {#4160 all: [], }

DD of relevant information on record:

+exists: true +wasRecentlyCreated: false -updating: true -versionableDirtyData: [] -reason: null

versioningEnabled: true

How can I create a version on this record

nonoesp commented 2 years ago

Hi @JurjenRoels – according to this method, versions are only saved on initial creation and updates. But you're saving without making any modifications to the model.

I've also missed that functionality when adding this library to models that didn't have it before with a populated database. One thing you could do is recreate all models from scratch with existing data, but I know that's not the best option.

You also need to ensure the fields you update aren't included in the $dontVersionFields property of your model.

I hope this helps.

JurjenRoels commented 2 years ago

Hi,

I think I will make a generic function that I can add to a handler I call on every create or update of records. It will verify if there is a currentversion and otherwise store a first one.

Hopefully this will be added to the package oneday.

Regards

nonoesp commented 2 years ago

Sounds good!

Feel free to add this method to the original class as a pull request, or at least share your workaround for others who run into the same issue.

Thanks!

JurjenRoels commented 2 years ago

Hi, we have build a whole system around models. My solution will be specific to the solution. I will post it here anyway. It could be added to a save function or an event.

JurjenRoels commented 2 years ago

//reason is always set when versioning is enabled on the storage of the model
if (isset($this->reason)) {
            // save the comment if set$version = $this->model->currentVersion();
            if ($version == null) {
                //We have an existing record, but not a version
                //Create a new version

                $version = new Version;
                $version->versionable_id = $this->model->getKey();
                $version->versionable_type = method_exists($this->model, 'getMorphClass') ? $this->model->getMorphClass() : get_class($this->model);
                $version->user_id = Auth::check() ? Auth::id() : null;

                $versionedHiddenFields = $this->model->versionedHiddenFields ?? [];
                $this->model->makeVisible($versionedHiddenFields);
                $version->model_data = serialize($this->model->attributesToArray());
                $this->model->makeHidden($versionedHiddenFields);
                $this->reason .= 'Created initial Version from database';
            }

                $version->reason = $this->reason;
                $version->save();

        }