【问题标题】:Laravel save multi part formLaravel 保存多部分表单
【发布时间】:2019-02-18 13:01:08
【问题描述】:

我有一个由 3 部分组成的表单,我希望能够在每次提交后更新数据库。有一个表格包含以下所有字段。

form1 asks for first and last name
form2 asks for email and phone
form3 asks for city and state

在我的控制器中,我有 3 个单独的函数来保存表单的每个步骤:

public function name(Request $request){
    $lead = Lead::firstOrNew(123);
    $lead->firstName = $request->get('firstName ');
    $lead->lastName = $request->get('lastName');
    $lead->save();
    return redirect('/form2');
}

public function info(Request $request){
    $lead = Lead::find(123);
    $lead->email = $request->get('email');
    $lead->phone = $request->get('phone');
    $lead->save();
    return redirect('/form3');
}

public function address(Request $request){
    $lead = Lead::find(123);
    $lead->city = $request->get('city');
    $lead->state = $request->get('state');
    $lead->save();
    return redirect('/done');
}

有没有办法将它与一个更新功能结合起来?

【问题讨论】:

    标签: php database laravel forms eloquent


    【解决方案1】:

    你可以重构方法来调用一个通用的“更新”函数。请参阅下面的示例代码。

    public function name(Request $request){
        $this->update(123, $request);
        return redirect('/form2');
    }
    
    public function info(Request $request){
        $this->update(123, $request);
        return redirect('/form3');
    }
    
    public function address(Request $request){
        $this->update(123, $request);
        return redirect('/done');
    }
    
    private function update($id, $request) {
        $lead = Lead::find($id);
        foreach ($field as ['firstName', 'lastName', ...]) {
            if ($request->has($field)) {
                $lead->{$field} = $request->get($field);
            }
        }
        $lead->save();
    }
    

    【讨论】:

    • 您必须将$request 作为参数传递给update 函数,否则它将不可用
    • 好收获。更新
    【解决方案2】:

    只需进行条件检查,更新模型并定义重定向 url:

    public function info(Request $request) {
        $lead = Lead::firstOrNew(123);
    
        if ($request->has('firstName') && $request->has('lastName')) {
            $lead->firstName = $request->get('firstName ');
            $lead->lastName = $request->get('lastName');
            $redirect = '/form2';
        } else if ($request->has('email') && $request->has('phone')) {
            $lead->email = $request->get('email');
            $lead->phone = $request->get('lastName');
            $redirect = '/form3';
        } else if ($request->has('city') && $request->has('state')) {
            $lead->city = $request->get('city');
            $lead->state = $request->get('state');
            $redirect = '/done';
        }
    
        $lead->save();
    
        return redirect($redirect);
    }
    

    另外,您可以通过update 进行组更新,只需确保将模型中的属性列入白名单

    public function info(Request $request) {
        $lead = Lead::firstOrNew(123);
        $lead->update($request->all());
    
        if ($request->has('firstName') && $request->has('lastName')) {
            $redirect = '/form2';
        } else if ($request->has('email') && $request->has('phone')) {
            $redirect = '/form3';
        } else if ($request->has('city') && $request->has('state')) {
            $redirect = '/done';
        }
    
        return redirect($redirect);
    }
    

    或者我最好在表单中添加一个重定向变量,例如:

    <input type="hidden" name="redirect" value="form1">
    

    并简化您的控制器方法,例如:

    public function info(Request $request) {
        $lead = Lead::firstOrNew(123);
        $lead->update($request->all());
    
        return redirect($request->input('redirect'));
    }
    

    【讨论】:

      【解决方案3】:

      您可以为所有三个表单添加一个隐藏字段(但使用名称名称,例如form_name),并设置它们的值以识别表单(form1form2form3),当它是提交。然后在您的控制器中,检查请求中form_name 字段的值以确定您要重定向到的位置,如下所示:

      public function info(Request $request) {
          $lead = Lead::firstOrNew(123);
          $lead->update($request->all());
      
          //this will be from the hidden field (form_name)
          $form_type = $request->get('form_name');
      
          if ($form_type == 'form1') {
              $redirect = '/form2';
          } else if ($form_type == 'form2') {
              $redirect = '/form3';
          } else if ($form_type == 'form3') {
              $redirect = '/done';
          }
      
          return redirect($redirect);
      }
      

      【讨论】:

        【解决方案4】:

        如果您有使用 javaScript 的选项,则将第一个和第二个表单数据保存在 cookie 或本地存储中,当用户到达表单的最后一部分时,然后从 cookie 或本地存储中取出数据,然后添加最后一个表单,但将它们保留在隐藏的输入中。

        【讨论】:

          【解决方案5】:

          鉴于 HTTP 请求是无状态的(这意味着每个请求对它之前和之后的请求一无所知),我宁愿您使用会话,这样您就可以像 redirect 一样从一个 @ 存储信息987654322@ 给另一个。在这种情况下,您的代码应如下所示:

          <?php
          
          public function name(Request $request){
              Session::put('nameData', $request->all());   //Store the info from form1 in session and redirect to form2
              return redirect('/form2');
          }
          
          public function info(Request $request){
              $validSessionData = Session::has('nameData');
          
              if (!$validSessionData) {    //Check if the user filled form1, if not, go back to form1
                  return redirect('/form1');
              }
          
              $nameAndInfo = Session::pull('nameData', []) + $request->all();  //Merge the info from form1 with info from form2. You could decide to keep them separate and merge later.
          
              Session::put('nameAndInfo', $nameAndInfo);
              return redirect('/form3');
          }
          
          public function address(Request $request){
              $validSessionData = Session::has('nameAndInfo');
          
              if (!$validSessionData) {   Another check. You could also extend this by checking for form2 session data
                  return redirect('/form1');
              }
          
              $allData = Session::pull('nameAndInfo', []) + $request->all();  //Merge all session data
              $lead = Lead::firstOrNew(123);
              $lead->firstName = $allData['firstName'];
              $lead->lastName = $allData['lastName'];
              $lead->email = $allData['email'];
              $lead->phone = $allData['phone'];
              $lead->city = $allData['city'];
              $lead->state = $allData['state'];
          
              $lead->save();
              return redirect('/done');
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-12-09
            • 2021-07-17
            • 2021-12-12
            • 1970-01-01
            • 2020-05-06
            • 2019-04-16
            • 2016-12-03
            • 1970-01-01
            相关资源
            最近更新 更多