laravel - Laravel 大规模更新,依然火的事件
问题描述
如文档中所述,laravel 不会在批量更新/插入/删除时触发事件。 https://laravel.com/docs/5.8/eloquent#events
它为此使用 Builder 并且不会触发事件。
例如,有没有办法在大规模更新后仍然可以触发事件?我只需要查询生成器自己提取所需的信息(日志目的)。
解决方案
这实际上是可能的,但是您必须扩展 Eloquent 构建器,覆盖更新/插入方法并将事件发送到那里。一直在玩它......需要工作,但基本思想如下:
class Test extends Model
{
protected $guarded = [];
public $dispatchesEvents = [
'saved' => SavedTest::class
];
/**
* INCLUDE this as a trait in your model.
* Overwrite the eloquentBuilder.
*
* @param \Illuminate\Database\Query\Builder $query
* @return \Illuminate\Database\Eloquent\Builder|static
*/
public function newEloquentBuilder($query)
{
return new TestBuilder($query);
}
}
扩展 eloquent builder...
class TestBuilder extends Builder
{
/**
* Update a record in the database and fire event.
*
* @param array $values
* @return int
*/
public function update(array $values)
{
// normal eloquent behavior.
$result =$this->toBase()->update($this->addUpdatedAtColumn($values));
/*
* Fire event.
*/
if($result){
if( $event = Arr::get($this->model->dispatchesEvents,'saved')){
// at the attributes.
$this->model->fill($this->addUpdatedAtColumn($values));
$queryBuilder =$this->toBase();
event(new $event($this->model,$queryBuilder));
}
}
}
public function insert(array $values)
{
// same idea..
}
}
事件类:
class SavedTest
{
use SerializesModels;
public $model;
public $query;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($model,$query =null)
{
$this->model = $model;
$this->query = $query;
}
}
听者。
class SavedTestEvent
{
/**
* Create the event listener.
*
*
*/
public function __construct()
{
}
/**
* Handle the event.
*
* @param object $event
* @return void
*/
public function handle($event)
{
// The model , with the attributes.
dump($event->model);
// the query builder , you could extract the wheres or whatever to build your own log for it.
dump($event->query);
}
}
推荐阅读
- python - 获取类属性的属性名
- redux - RXJS 订阅主题 - 操作必须是普通对象。使用自定义中间件进行异步操作
- java - Eclipse 霓虹灯挂起加载 org.eclipse.ui.navigator
- python - 如何使用 discord.py 事件处理程序 on_voice_state_update 仅在用户加入语音频道时运行
- http - 避免对缓存文件的请求
- c# - dotnet core 2 Web C# 对象引用未设置为对象的实例?
- c++ - 在 C++ 中以编程方式更改 Enable32BitAppOnWin64
- azure-data-lake - 多列上的连接是否存储笛卡尔积?
- javascript - html 按钮更改 div 内容或再次切换
- c# - System.InvalidOperationException: 'XML 文档 (0, 0) 中存在错误。'