【问题标题】:Copy a record and it's descendants in Laravel 5.4在 Laravel 5.4 中复制一条记录及其后代
【发布时间】:2017-12-19 18:46:15
【问题描述】:

我有当前的结构化数据库和 Eloquent 模型。

文档

身份证

页面

id, document_id

资产

id, page_id

所以我的文档有很多页面和很多资产。

我的文档模型中有一个非常丑陋的方法,它一直在工作,直到现在它迭代所有页面,然后是资产并复制它们,将新外键存储在新记录中。

    foreach ($pages as $page) {
        $replicatedPage = $page->replicate();
        $replicatedPage->document_id = $newDocument->id;
        $replicatedPage->save();

        foreach ($page->assets as $asset) {
            $replicatedAsset = $asset->replicate();
            $replicatedAsset->page_id = $replicatedPage->id;
            $replicatedAsset->save();
        }
    }

不幸的是,由于人们要上传近 200 个页面,每页包含 200 个资产(总共 40,000 个资产),因此这变得非常缓慢。

我也研究了 saveMany() 函数,但在底层它只是通过迭代所说的 ID 完成了我上面所做的事情。

我真正需要的是一个很好的查询构建器来在 SQL 级别复制所有这些,但我不知道如何做到这一点。甚至可以将原始 SQL 语句嵌入到原始查询构建器函数中。

有什么想法吗?

【问题讨论】:

    标签: mysql laravel eloquent laravel-5.4 laravel-query-builder


    【解决方案1】:

    使用insert() 方法使其更快。急切地加载文档及其所有页面和资产,迭代此数据并为每个表构建一个数组。 pages 表的示例(对 assets 表执行相同操作):

    $replicatedPages = [];
    foreach ($pages as $page) {
        $replicatedPages[] = $page->toArray(); // Probably you'll need to remove ID column.
    }
    Page::insert($replicatedPages);
    

    使用这种方法,您将只执行两个查询来插入所有文档的页面和资产,而不是执行 40000 个查询。

    【讨论】:

    • 我刚刚看到的这个想法的唯一问题是数据库插入不会返回所有 ID。
    • @BradBird 如果需要,您可以手动将 ID 放入 foreach 循环中。
    猜你喜欢
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 2013-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-10
    • 1970-01-01
    相关资源
    最近更新 更多