Function is not triggered when updated inside model
P粉752826008
2023-08-08 16:31:55
<p>我有一个像这样的模型:</p>
<pre class="brush:php;toolbar:false;">class Equipment extends Model
{
use HasFactory,softDeletes;
protected $table = 'equipments';
protected $fillable = ['station_id', 'parent_id', 'code', 'name', 'description', 'creator_id','deletor_id','updator_id'];
protected $softDelete = true;
protected $dates = ['deleted_at'];
public static function boot()
{
parent::boot();
//it doesn't called at all!
static::updated(function (Model $model) {
Log::error('calling refreshTree');
$model->refreshTree();
});
static::created(function (Model $model) {
$model->refreshTree();
});
static::deleted(function (Model $model) {
$model->refreshTree();
});
}
public function refreshTree(){
Log::error('refreshTree');
$equipment = DB::table('equipments')->get();
$treeData = $this->generateTree($equipment);
$jsonData = json_encode($treeData);
Redis::set(config('redis.EquipmentTree'),$jsonData);
}
private function generateTree($data, $parentId = 0) {
$tree = [];
foreach ($data as $item) {
if ($item->parent_id == $parentId) {
$children = $this->generateTree($data, $item->id);
$node = [
'id' => $item->id,
'text' => $item->name,
'editURL'=>route('dashboard.basic-info.equipments.edit',['id'=>$item->id]),
'children' => $children
];
if(count($children) <= 0)
unset($node['children']);
array_push($tree, $node);
}
}
return $tree;
}
}</pre>
<p>当我创建模型时,创建函数被触发,但当我更新模型时,更新函数没有被触发</p>
<pre class="brush:php;toolbar:false;">//Equipment::where('id',$id)->update(['parent_id'=>$recordTarget['id']]); //它没有生效
//我也尝试了这个:
$equipment = Equipment::find($id);
$equipment->parent_id = $recordTarget['id'];
$equipment->save();</pre>
<p><br /></p>
When using a query builder instance or batch update, the event listener will not fire even if you only operate on one row
To trigger it, you need to use a model instance
This is also equivalent to
And you can see that calling update() on the model is different from calling update() on the query builder.
When you consider that to trigger these events, the code needs an instance of the model to work with, like static::updated(function (Model $model) {. If your query is different, for example Equipment: :where('id','>',$id), in order to handle all events, it needs to query all affected rows, generate model instances for them, and then call the event using these models.
This Will reduce performance
But if there is no other way, you can do it explicitly