【问题标题】:Laravel get last inserted dataLaravel 获取最后插入的数据
【发布时间】:2017-12-10 04:08:15
【问题描述】:

请在下面找到代码,这里我正在尝试创建主记录并根据 id 添加相关数据。

    $country = new Country;

    $country->name = $request->post('country-name');
    $country->xyz  = $request->post('xyz');

    if($country->save()) {
        $n = count($request->post('bname'));

        for ($i = 0; $i < $n; $i++) {
            $dimention = new BoxDimentions;

            $dimention->name = $request->post('bname')[$i];
            $dimention->xyz  = $request->post('xyz')[$i];
            $dimention->cid  = $country->id;

            $dimention->save();
        }
    }

是否有任何内置的 laravel 功能可以在操作后获取有关国家和 BoxDimentions 的所有信息(包括 id、日期时间戳等)?

我在 Country Model 类“盒子”中创建了一个关系,它将返回所有盒子信息。我知道我可以使用具有上次创建的国家/地区 ID 的另一个查询来获取数据。我不想再查询,因为我相信我们已经掌握了所有数据。

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    执行save() 后,您将获得带有其 ID 的模型。您可以使用$model-&gt;id 访问它。所以,你可以这样做:

    $country = new Country;
    
    $country->name = $request->post('country-name');
    $country->xyz  = $request->post('xyz');
    
    $dimentionIds = [];
    
    if ($country->save()) {
        $n = count($request->post('bname'));
    
        for ($i = 0; $i < $n; $i++) {
            $dimention = new BoxDimentions;
    
            $dimention->name = $request->post('bname')[$i];
            $dimention->xyz  = $request->post('xyz')[$i];
            $dimention->cid  = $country->id;
    
            $dimention->save();
    
            $dimentionIds[] = $dimention->id;
        }
    }
    
    dd($dimentionIds, $country->id);
    

    如果您需要所有数据,只需保存整个对象:

     $dimentions[] = $dimention;
    

    【讨论】:

    • 我认为他想获取所有数据,所有行
    • @CavidKərimov 我认为 OP 只需要 ID。感谢您的指正。我已经更新了我的答案。
    • 我猜对了,当您想要所有信息时,您的意思是可能有一些列获得了数据库设置的一些默认值,因此您的新实例没有它们?
    【解决方案2】:

    我仍然不完全确定你在问什么。如果可以进行类似这样的新查询:

    $country->refresh();
    

    将从数据库中重新加载当前模型以及从数据库中重新加载任何已加载的关系。

    $country->id;
    $country->created_at;
    $firstBox = $country->boxes->first();
    $firstBox->id;
    $firstBox->created_at;
    

    您似乎希望不再有任何查询发生,这也可以。只要您的数据库没有设置您需要的默认值,您就可以实际将这些记录添加到关系中,而不是重新加载关系。

    假设你有你的国家并且你加载了那个关系:

     $country->load('boxes');
     // or maybe because of eager loading
     $country = Country::where(...)->with('boxes')->first();
    
     ...
     foreach ( something ) {
         $dimention = new BoxDimentions;
         ...
         $dimention->save();
         $country->boxes->add($dimention);
     }
    
     return $country;
    

    $country-&gt;boxes 将拥有您之前加载的所有项目和所有新记录。

    如果你只想要新的,你可以将关系设置为新的集合。

    $country->setRelation('boxes', $country->newCollection());
    
    foreach ( something ) {
        ...
        $country->boxes->add($dimention);
    }
    

    现在$country-&gt;boxes 只是那些新的。

    【讨论】:

      【解决方案3】:

      不幸的是,save() 返回 bool。

      您的解决方法是使用create() 静态包装器,这样您就可以获得最近创建的模型实例。

      您可能希望重构该代码,因此在您的 Country 模型中您将创建一个类似这样的函数(假设您已定义 Country 和 BoxDimensions 关系):

      您的国家模式:

      public function addBoxDimensions(array $data){
      
          return $this->boxes()->create($data);
      }
      

      然后你的控制器看起来像这样:

      $country = new Country;
      
      $country->name = $request->post('country-name');
      
      $country->xyz  = $request->post('xyz');
      
      if($country->save()) {
      
          $n = count($request->post('bname'));
      
      for ($i = 0; $i < $n; $i++) {
      
                  // Here I will use relationships to create box dimensions for given country that's why I do not need to initialize BoxDimentions
                 // $dimention = new BoxDimentions;
      
                 $dimention = $country->addBoxDimensions([
                   'name' = $request->post('bname')[$i],
                   'xyz'  = $request->post('xyz')[$i],
                   'cid'  = $country->id 
                  ]);
             }
              //here you can return the country with all the box dimentions
              // also used eager loading to load boxdimensions so we can aviod N+1
      
             return $dimention->load('boxes');  
      
      
      
              }
      

      【讨论】:

      • 当你调用 save 时,你就有了模型(这是你调用 save 的东西)...create 只是在一个新实例上调用 save
      • 是的,但是我要退回链上的国家/地区盒子!所以创建调用保存但随后方法返回 $this->boxes() ;)
      • 我同意@lagbox。此外,您正在尝试在盒子实例上加载盒子关系。即使您修复它,使用这种方法也会执行额外的查询。最后一个问题是您将加载属于国家/地区的所有框,而不是您刚刚创建的框。
      • @AlexeyMezenin 我不确定您是否正确阅读了我的答案,我从那里添加了 Country 模型上的方法我加载了框。是的,这将执行一个附加查询,但他不会在每次 for 循环执行正确时调用查询!
      • 不,它是一个 Box .. 您没有从该方法返回 $this,而是返回您创建的新 Box。
      【解决方案4】:

      如果您已经设置了关系,以下内容不会为您完成这项工作吗?当然这可能是另一个查询,但它会将数据作为集合返回,这样您就不用自己处理了。

      dd($country->boxes);
      

      【讨论】:

        猜你喜欢
        • 2022-01-17
        • 2015-08-10
        • 2012-01-21
        • 1970-01-01
        • 2014-01-31
        • 2015-09-13
        • 2016-10-24
        • 2016-12-19
        相关资源
        最近更新 更多