Laravel 5.2 多模型 save()

Posted

技术标签:

【中文标题】Laravel 5.2 多模型 save()【英文标题】:Laravel 5.2 multiple model save() 【发布时间】:2016-07-25 21:42:03 【问题描述】:

我需要通过表单一次恰好存储三个页面。我想以与模型 save() 方法类似的方式保存,因为这会自动更新记录时间戳

如何同时处理多条记录?

我的页面模型

namespace App;
use Illuminate\Database\Eloquent\Model;

class Page extends Model
     protected $table = 'simple_pages';

我的代码

public function createPages(Request $request) // I use Page at the top
     $data = [
          [
          'title'=> $request->first,
          'content'=> $request->firstCont
          ],[
          'title'=> $request->second,
          'content'=> $request->secondCont
          ][
          'title'=> $request->third,
          'content'=> $request->thirdCont
          ]
     ];
     Page::unguard();
     $pages = new Page($data);
     $pages->save(); // Something like this would be amazing
     Page::reguard();

注意:我强烈反对创建多个 Page 模型实例,然后循环它们以分别保存它们。另外,我不想使用数据库插入,因为它不会自动更新记录时间戳。

【问题讨论】:

我知道这是一个老问题,但解决方案是Page::insert($data)。看到这个答案:***.com/a/29723968/172790 【参考方案1】:

经过长时间的搜索,我发现了这个:

        $eloquentCollection->each(function ($item, $key) 
            $item->save();
        );

是的,它是迭代,但看起来没有其他方法可以保存多个模型。唯一的选择是使用DB::insert(),但要注意没有自动更新的时间戳。

另外,如果您愿意保存太多的 eloquent 模型,请分块保存它们,因为可能存在内存问题(或将它们推送到 Queue)。

【讨论】:

【参考方案2】:

如果您阅读手册Mass Assignment。

public function createPages(Request $request) // I use Page at the top
     $data = [
          [
          'title'=> $request->first,
          'content'=> $request->firstCont
          ],[
          'title'=> $request->second,
          'content'=> $request->secondCont
          ][
          'title'=> $request->third,
          'content'=> $request->thirdCont
          ]
     ];

     Page::unguard();
     $pages = Page::create($data);
     Page::reguard();

【讨论】:

感谢您的回答。我已经阅读了官方文档,但它对我没有帮助。 Page::create($data) 创建异常(preg_match() 期望参数 2 是字符串,给定数组);我也尝试过 Page::create([ ... first ....],[ ... second ....],[ ... third ....]),但它只是将单个空白记录插入到数据库,这不是我想要实现的。 但是,如果您的列未列在 protected $fillable = [] 内,它将无法工作。如果您设置了$fillable 并且您的数组已设置,您需要确保您的值实际上是字符串而不是数组。即$request->first$request->firstCont 我使用了模型 unguard() 和 reguard() 模型方法。因此,受保护/可填充在这里不应该是一个问题(或者它是一个问题吗? - 如果它是一个问题,Laravel 会抛出质量分配异常)。关于我的请求内容,我 100% 确定。我最近检查了 dd()。它们都是字符串。 @Fusion true Unguard 会使$fillable 无关紧要,错过了。查看create,它通过__construct 到fill 也许你可以调试一下?【参考方案3】:

这是我发现实施的最佳解决方案

User::create([array of multiple user detail arrays])

避免执行与要添加的条目一样多的查询

Allow Eloquent to save multiple records at once

【讨论】:

【参考方案4】:
$data = [
      [
      'title'=> $request->first,
      'content'=> $request->firstCont
      ],[
      'title'=> $request->second,
      'content'=> $request->secondCont
      ][
      'title'=> $request->third,
      'content'=> $request->thirdCont
      ]
 ];

foreach($data as $page) 
      Page::create($page);
    

应该能解决你的问题

【讨论】:

以上是关于Laravel 5.2 多模型 save()的主要内容,如果未能解决你的问题,请参考以下文章

laravel 5.2 中的表单模型绑定

Laravel 5.2 pluck() 来自 Eloquent 模型集合的多个属性

雄辩的模型属性作为骆驼案例 [Laravel 5.2] [Dingo API]

在 laravel 5.2 中使用单个命令制作模型和迁移

Laravel 5.2 使用 uuid 字符串作为 id 的隐式路由模型绑定

Laravel 5.2路径模型使用方法和控制器进行绑定