Laravel 获取最近插入的数据

3
请看下面的代码,我正在尝试创建主记录,并基于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模型类中创建了与“boxes”相关的关系,该关系将返回所有箱子信息。我知道可以使用另一个查询来获取最后创建的国家ID的数据。我不想进行另一个查询,因为我相信我们手头已经有了所有数据。

4个回答

2
执行save()后,您将得到带有其ID的模型。您可以使用$model->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;

我认为他想获取所有数据,即所有行。 - Javid Karimov
1
@CavidKərimov 我以为 OP 只想要 ID。感谢更正。我已更新我的答案。 - Alexey Mezenin
我猜测你的意思是当你需要所有信息时,可能会有一些列得到数据库设置的默认值,因此你的新实例没有它们? - lagbox

1

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

$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->boxes会包含之前加载的所有项目和新记录。

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

$country->setRelation('boxes', $country->newCollection());

foreach ( something ) {
    ...
    $country->boxes->add($dimention);
}

现在,$country->boxes 只是那些新的。

0
如果您已经设置了关联,那么以下代码不就可以为您完成工作吗?虽然这可能会生成另一个查询,但它将返回数据集合并帮助您省去自己处理的麻烦。
dd($country->boxes);

0

很不幸,save() 返回布尔值。

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

您可能想要重构该代码,在您的 Country 模型中,您可能会创建一个像这样的函数(假设您已经定义了 Country 和 BoxDimensions 的关系):

您的 Country 模型:

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');  



        }

1
当你在模型上调用save时,你就拥有了这个模型(它就是你在调用save的那个东西)... create只是在一个新实例上调用save - lagbox
是的,但你从中返回了 BoxDimentions 对象。我并没有说额外的查询将在循环中执行。它只会执行一次。但仍然是一个额外的查询。 - Alexey Mezenin
@lagbox $dimention 是 stdObject 的属性,来自于 Country :) 然后 load() 懒加载 Country 中的 boxes!这个功能运行正常,之前今天遇到过类似的问题!或者我应该说,稍微复杂一些,使用 vue ! - Leo
1
不是 $this,你返回的是你创建的新盒子。 - lagbox
你仍在尝试将boxes加载到Country而不是Box上...在关系上调用create会返回你刚刚创建的新模型...你正在方法中创建一个Box,所以你正在返回一个Box...现在,如果那个for循环没有运行,你可能会得到一个未定义的变量。 - lagbox
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接