用laravel中的一个请求更新多个记录


updating several records with one request in laravel

一些快速上下文:我有一个sql表和一个雄辩的模型JobCards和每个JobCard有几个操作属于它。我有操作的表和模型。我的应用程序的用户浏览和编辑JobCards,但是当我说编辑Jobcard时,这可以包括与Jobcard相关联的操作。我有一个页面,其中用户可以编辑操作为某个JobCard,我提交的数据作为操作数组。

我想要一个干净的方法来更新JobCard操作的数据。有三种不同的操作,我可能需要,也可能不需要:

  1. 用新数据更新现有操作
  2. 创建新的操作
  3. 删除操作

我试着处理前两个,事情已经变得混乱了。我仍然需要一种方法来删除操作,如果它不存在于在请求中发送的数组中。

下面是我的代码:

public function SaveOps(Request $a)
{
    $JobCardNum = $a -> get('JobCardNum');
    $Ops = $a -> get('Ops');
    foreach ($Ops as $Op) {
        $ExistingOp = JobCardOp::GetOp($JobCardNum, $Op['OpNum'])->first();
        if(count($ExistingOp)==0) {
            $NewOp = new JobCardOp;
            $NewOp -> JobCardNum = $JobCardNum;
            $NewOp -> fill($Op);
            $NewOp -> save(); 
            $this->UpdateNextOpStatus($JobCardNum, $NewOp);
        }
        else {
            $ExistingOp -> fill($Op);
            $ExistingOp -> save();
        }             
    }

有没有人可以帮助删除部分和/或帮助使我的代码更整洁。

你的方法应该是这样的。请注意,我添加了一个新方法getCache($JobCardNum),该方法将获得每个作业卡的操作数组(假设您的模型被设计为以这种方式相关),该方法将只到DB一次,以获得此method call所需的所有操作,而不是一个接一个地获得它们(在foreach循环中),这样您就可以确保对DB的昂贵调用只完成一次。另一方面,您以数组的形式获得了JobCard的操作,准备与新操作(在请求中)进行比较,该方法的返回将以(key=>value, key是操作编号,value是操作对象本身)的形式。

/**
 * This function will get you an array of current operations in the given job card
 * @param $JobCardNum
 * @return array
 */
public function getCache($JobCardNum)
{
    /**
     * asuming that the relation in your model is built that way. if not you should then
     * use JobCardOp::all(); (Not recommended because it will get a lot of unnecessary 
     * data )
     */
    $ExistingOps = JobCardOp::where('job_card_id', '=', $JobCardNum);
    $opCache = array();
    foreach ($ExistingOps as $Op) {
        $opCache[(string)$Op->OpNum] = $Op;
    }
    return $opCache;
}
public function SaveOps(Request $a)
{
    $strOpNum = (string)$Op['OpNum'];
    $JobCardNum = $a->get('JobCardNum');
    $Ops = $a->get('Ops');
    $opCache = $this->getCache($JobCardNum);
    foreach ($Ops as $Op) {
        if (!isset($opCache[$strOpNum])) {
            $NewOp = new JobCardOp;
            $NewOp->JobCardNum = $JobCardNum;
            $NewOp->fill($Op);
            $NewOp->save();
            $this->UpdateNextOpStatus($JobCardNum, $NewOp);
        } else {
            $ExistingOp = $opCache[$strOpNum];
            $ExistingOp->fill($Op);
            $ExistingOp->save();
        }
        unset($opCache[$strOpNum]);
    }
    /*
     * at this point any item in the $opCache array must be deleted because it was not 
     * matched in the previous for loop that looped through the requested operations :)
     */
    foreach ($opCache as $op) {
        $op->delete();
    }
}