Laravel 更新 eloquent 事件:旧数据与新数据相同
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40061667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel updating eloquent event: old data same as new
提问by piotr
I've created News
model NewsObserver
associated to it. I want to do some logic with old and new data passed to model on updated
/updating
event, but dump of passed model have identical attributes as original attributes, except 'updated_at'
field. What am I doing wrong?
我已经创建了与之关联的News
模型NewsObserver
。我想对传递给updated
/updating
事件模型的旧数据和新数据进行一些逻辑处理,但是传递模型的转储与原始属性具有相同的属性,'updated_at'
字段除外。我究竟做错了什么?
public function updating(News $item)
{
dd($item);
}
Here is where observer is attached
这是观察者所在的位置
use App\Observers\NewsObserver;
use App\Observers\FileObserver;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
News::observe(NewsObserver::class);
File::observe(FileObserver::class);
}
And here is a part of my NewsObserver
with my updating
event. dd
of $item
contains only old data
这是NewsObserver
我的updating
活动的一部分。dd
of$item
只包含旧数据
namespace App\Observers;
use App\News;
class NewsObserver
{
/**
* Listen to the News updated event.
*
* @param \App\News $item
* @return void
*/
public function updating(News $item)
{
$publish_at = request()->input('publish_at');
$item->publish_at = $publish_at ? $publish_at : $item->publish_at;
dd($item);
}
The example of described dd
is provided below. New and original attributes are identical except updated_at
property. But the new title should be news NEW title
. Of course new data is saved properly in database, but in updating
or update
event I don't see 'dirty' attributes
dd
下面提供所描述的示例。除了updated_at
属性之外,新的和原始的属性是相同的。但新标题应该是news NEW title
. 当然,新数据已正确保存在数据库中,但在updating
或update
事件中我看不到“脏”属性
#attributes: array:13 [▼
"id" => 7
"created_at" => "2016-10-15 19:46:04"
"updated_at" => "2016-10-15 19:47:11"
"publish_at" => "2016-10-15 19:46:00"
"title" => "news OLD title"
"slug" => "news-old-title"
"content" => "<p>news OLD content</p>"
"lead" => ""
#original: array:13 [▼
"id" => 7
"created_at" => "2016-10-15 19:46:04"
"updated_at" => "2016-10-15 19:46:21"
"publish_at" => "2016-10-15 19:46:00"
"title" => "news OLD title"
"slug" => "news-old-title"
"content" => "<p>news OLD content</p>"
回答by num8er
I think You're looking for:
我认为您正在寻找:
getOriginal, getAttributes, isDirty, getDirty and so on...
getOriginal、getAttributes、isDirty、getDirty 等等...
please read docs and use whichever You want: https://laravel.com/api/5.3/Illuminate/Database/Eloquent/Model.html#method_getOriginal
请阅读文档并使用任何你想要的:https: //laravel.com/api/5.3/Illuminate/Database/Eloquent/Model.html#method_getOriginal
So I'll do that process this way:
所以我会这样做:
$before = $item->toArray();
$item->title = request()->input('title', $item->title);
// some changes
if($item->save()) {
$after = $item->toArray();
$changes = array_diff_assoc($before, $after);
Logs::create(compact('before', 'after', 'changes'));
}
or that way more elegant:
或者那样更优雅:
public function updating(News $item) {
$changes = array();
foreach($item->getDirty() as $key => $value){
$original = $model->getOriginal($key);
$changes[$key] = [
'old' => $original,
'new' => $value,
];
}
Log::create(['model' => __CLASS__, 'changes' => serialize($changes)]);
});
or to overload save
operator in model class with this:
或save
在模型类中重载运算符:
trait LogSave {
public function save(array $options = array()) {
$changed = $this->isDirty() ? $this->getDirty() : false;
parent::save();
if($changed) {
// log changes
}
}
}
class News extends Model {
use LogSave;
}
also I've to ideas:
我也有想法:
1) what about having old = true
flag in model and when doing update actually to create new record and update all old
version with old = true
in this case it will be easy to manage/rollback changes just by updating old = false
necessary version. to keep track of the news id You'll have to keep some uuid
field in Your table/model.
1)如何old = true
在模型中设置标志以及在实际进行更新以创建新记录并更新所有old
版本时如何,old = true
在这种情况下,只需更新old = false
必要的版本即可轻松管理/回滚更改。跟踪新闻 ID 你必须uuid
在你的表/模型中保留一些字段。
2) to have news_revisions
and just to create old News
($item
) object to NewsRevision
and update the current one.
2) 拥有news_revisions
并且只是创建旧News
( $item
) 对象NewsRevision
并更新当前对象。
回答by halfer
(Posted solution on behalf of the OP).
(代表OP发布解决方案)。
Problem solved. The one thing I didn't post here is the $item->touch()
method used few lines before. I forgot that may fire update event only on updated_at
field. My mistake. Thanks for all your help!
问题解决了。我没有在这里发布的一件事是$item->touch()
之前使用了几行的方法。我忘了可能只在updated_at
现场触发更新事件。我的错。感谢你的帮助!