Avoid changing updated_at on restore
Closed this issue · 8 comments
First thank you for this great package!
As far as I can tell, when cascade-restoring a model, the updated_at column is changed which is a problem for my application. Is it a Laravel problem? Is it this package, and if so, is it the intended behaviour? And finally, is there a way to disable this behaviour?
Thank you in advance!
This is a functionality of Laravel and not a Laravel problem.
The use of these fields is explained in the documentation: https://laravel.com/docs/5.6/eloquent#eloquent-model-conventions
I paste you the code to use when you don't need timestamps columns.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = false;
}
Could you explain which is the problem you have? maybe I could help you!
Thank you for the quick reply :-)
So my problem is that I'm trying to implement a recover (undo delete) functionality on a forum system.
If I delete a discussion and then recover it, the updated_at field is updated, and since I need this field to keep track of most recently updated discussions,(I order by updated_at) it changes the order of display (it put a potentially 6 months old discussion first in list).
To say it differently, I'd like to have recover() only set null the deleted_at columns without touching the others columns.
I understand it's a specific use case, but on save() you can do it like this :
$model->save(['timestamps' => false]);
I'd like to have
$model->restore(['timestamps' => false]);
By the way, the application is here : https://github.com/philippejadin/agorakit
I will implement it as soon as possible :)
Great! Please note that $model->restore(['timestamps' => false]); doesn't work and afaict is not supported by laravel, so I don't know how to do it properly. I think that the updated_at column is already updated when a record is deleted (which make sense for most use cases but not mine, or general undo strategy where you want to restore a record exactly as it was before deletion).
Anyway I'm curious to see how you will solve this, learning opportunity for me there
To add to my previous comment, I think that for my use case, I'd better not cascade delete and recover at all, and just delete/recover a single element (be it a group, a discussion or a comment in my case) so the recover process doesn't propagate to parents (a comment belong to a discussion and a discussion belong to a group).
Thank you for your time!
@philippejadin This will be the best option because I'm checking Laravel code and I can't interact with model timestamps because when Laravel call runSoftDelete method restablish model with newQueryWithoutScopes method.
/**
* Perform the actual delete query on this model instance.
*
* @return void
*/
protected function runSoftDelete()
{
$query = $this->newQueryWithoutScopes()->where($this->getKeyName(), $this->getKey());
$time = $this->freshTimestamp();
$columns = [$this->getDeletedAtColumn() => $this->fromDateTime($time)];
$this->{$this->getDeletedAtColumn()} = $time;
if ($this->timestamps && ! is_null($this->getUpdatedAtColumn())) {
$this->{$this->getUpdatedAtColumn()} = $time;
$columns[$this->getUpdatedAtColumn()] = $this->fromDateTime($time);
}
$query->update($columns);
}
My idea was to edit the model timestamps in real time using property setted with config as config(['softcascade.timestamps' => false]).
//Set model timestamps
if (is_bool($this->timestamps)) {
$model = $relationModel->getModel();
$model->timestamps = $this->timestamps;
$relationModel = $relationModel->setModel($model);
}
I think it means something like :
"if you want to preserve exactly your models when recovering, don't cascade delete / recover in the first place" :-)
It makes sense and probably means it's a niche use case.
Thank you for taking the time to dig this.
@philippejadin You're welcome, it has been a pleasure. I think the same but another option could be to create a model that extends this by setting the timestamps = false property and using the new model when you don't want to change the date.