Function is not triggered when updated inside model
P粉752826008
P粉752826008 2023-08-08 16:31:55
0
1
482
<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>
P粉752826008
P粉752826008

reply all(1)
P粉165522886

When using a query builder instance or batch update, the event listener will not fire even if you only operate on one row

Equipment::where('id',$id) //right here you get a Builder instance
    ->update([]); //will not trigger the event listener as it is a mass update

To trigger it, you need to use a model instance

Equipment::where('id',$id)->first() //This returns a model instance
    ->update([]); //will trigger the event listener as it is a single instance update

This is also equivalent to

$equipment = Equipment::find($id);
$equipment->parent_id = ..;
$equipment->save();

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

$equipments = Equipment::where('id','>',$id)->get();
foreach ($equipments as $equipment) {
    $equipment->update(['parent_id'=>$recordTarget['id']]);
}
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template