php 如何在laravel中更新父模型?

wqsoz72f  于 2023-03-07  发布在  PHP
关注(0)|答案(1)|浏览(127)

我有一个项目,具有类似的功能,以trello(看板)有3个模型,这是项目,任务列表(列),任务(卡)。

  • 一个项目有许多列
  • 一列有多个任务
  • 一项任务有许多

子任务(子任务指模型本身)
每个模型都有一个名为“进度”的列。2当更新子模型时,必须更新此列。3进度是通过平均所有卡的进度来计算的。
产品型号:Project. php

class Project extends Model
{
    use HasFactory;

    protected $table = 'projects';

    public $timestamps = true;

    protected $fillable = [
        'id','title', 'description', 'actual_start', 'actual_end',
        'start', 'end','progress'
    ];

    public function updateProgress(){      
        $sum=0;
        if(count($this->columns)){
            for ($i = 0; $i < count($this->columns); $i++) {
                $list = $this->columns[$i];
                if($list->progress==null){
                    $list->progress=0;
                }
                $sum+=$list->progress;
            }
            $progress=$sum/count($this->columns);
            $this->progress=round($progress);
            $this->save();
        }
        return $this->progress;
    }
    
    public function scopeExclude($query, $value = []) 
    {
        return $query->select(array_diff($this->fillable, (array) $value));
    }

    public function lists(){
        return $this->hasMany(TaskList::class,'projects_id');
    }

TaskList.php

class TaskList extends Model
{
    protected $table = 'lists';
    
    protected $fillable = [ 'title', 'position', 'projects_id', 'start', 'end', 'actual_start', 'actual_end','progress' ];

    public static function boot() {
        parent::boot();

        static::saved(function($list){
            $list->project->updateProgress();
        });
    }

    public function updateProgress(){      
        $tes=[];
        if(count($this->cards)){
            $sum=0;
            for ($i = 0; $i < count($this->cards); $i++) {
                $task = $this->cards[$i];
                if($task->progress==null){
                    $task->progress=0;
                }
                $sum+=$task->progress;
                $tes[]=['id'=>$task->id,'progress'=>$task->progress,$task->cards];
            }
            $progress=$sum/count($this->cards);
            $this->progress=round($progress);
            $this->save();
        }
        return ['id'=>$this->id,'progress'=>$this->progress,'cards'=>$this->cards];
    }

    
    public function cards(){
        return $this->hasMany(Task::class,'lists_id');
    }
}

Task.php

class Task extends Model
{
    use HasFactory;
    
    protected $table = 'tasks';

    public $timestamps = true;

    protected $fillable = [
        'id','users_id', 'title', 'description', 'complete', 'end', 'start',
        'actual_start', 'actual_end', 'start_label', 'end_label', 
        'progress', 'is_subtask', 'lists_id','parent_task_id'
    ];

    protected $casts = [
        'progress' => 'double',
    ];
    
    public static function boot() {
        parent::boot();
        static::saving(function($task){
            if(!empty($task->start)  && !empty($task->end)){
                $start = Carbon::parse($task->start);
                $end = Carbon::parse($task->end);
                $days= $start->diffInDays($end);
                $task->days=$days+1;
            }       

            if(!empty($task->actual_start) && !empty($task->actual_end)){
                $actual_start = Carbon::parse($task->actual_start);
                $actual_end = Carbon::parse($task->actual_end);
                $work_days= $actual_start->diffInDays($actual_end);
                $task->work_days=$work_days+1;
            }
            
            if($task->parentTask){
                if($task->actual_end){
                    $task->progress=100;
                }else{
                    $task->progress=0;
                }
            }else{
                if($task->actual_end){
                    $task->progress=100;
                }else{
                    $task->progress=0;
                }
            }
            if($task->progress==100){
                $task->complete=true;
            }
            
            
        });
        
        static::saved(function($task){
            //is a subtask
            if($task->parentTask){
                // dd('subtask',$task->id,$task->complete,$task->progress,$task->parentTask,$task->list);
                $task->parentTask->updateProgress();
            }else{
                // dd('parent task',$task->id,$task->complete,$task->progress,$task->parentTask,$task->list);
                $task->list->updateProgress();
                // dd('list ',$task->list->updateProgress());
            }
        });

        static::deleting(function($task) { 
            foreach ($task->members as $i => $member) {
                $member->delete();
            }
            foreach ($task->cards as $k => $subtask) {
                $subtask->delete();
            }
            $task->tags()->detach();
            $task->task_members()->detach();
        });
    }

    public function updateProgress(){      
        if(count($this->cards)){
            $valuePerSubtask=100/count($this->cards);
            $completeSubtaskCounter=0;
            for ($i = 0; $i < count($this->cards); $i++) {
                $subtask = $this->cards[$i];
                if($subtask->complete){ 
                    $completeSubtaskCounter++; 
                }
            }
            $progress=$completeSubtaskCounter*$valuePerSubtask;
            $this->progress=$progress;
            $this->save();
            return [$this->progress,$progress];
        }
    }

    public function scopeExclude($query, $value = []) 
    {
        return $query->select(array_diff($this->fillable, (array) $value));
    }
    
   
    public function parentTask(){
        return $this->belongsTo(Task::class,'parent_task_id');
    }

    public function list(){
        return $this->belongsTo(TaskList::class,'lists_id');
    }
 
}

我无法从子任务更新父任务。正如您在Task.php模型中所看到的,我在调用$this->save()之后有一个updateProgress(),return [$this->progress, $progress];。在保存之前,我已经有了$this->progress=$progress。但是$this->progress仍然显示相同的结果。
[![第一项为$this->progress,第二项为$progress][1]][1] [1]:https://i.stack.imgur.com/RS2mq.png
我尝试覆盖touch()并将updateProgress()放入其中。但仍然没有显示预期的结果。
有什么建议吗?我错过什么了吗?

bejyjqdl

bejyjqdl1#

解决方案还可以是:
创建任务的观察者。

php artisan make:observer TaskObserver

然后在观察者中。

class UserObserver
{
    //SOME METHODS

   public function updated(Task $task)
   {
       /* Important, this will be done with all tasks on update in the tree
          like Task->task->task etc... unless you put some extra logic. But 
          this is the general idea
       */

       #search if parent
       if ($task->parent_task_id !== null) {
           //run progress
            $task->parentTask->updateProgress()
       }
   }

}

相关问题