如何在Laravel中复制具有嵌套关系的模型

时间:2016-08-04 23:21:13

标签: laravel laravel-5.1

我有一个有很多嵌套关系的模型。我首先加载它们:

<?php
$model = Model::where('id', $id)
    ->with(
        'relation1',
        'relation2',
        'relation2.subrelation1', 
        'relation2.subrelation2',
        'relation3', 
        'relation3.subrelation1', 
        'relation3.subrelation2',
        'relation3.subrelation3', 
        'relation3.subrelation4.subrelation', 
    )->get();
?>

以下是我如何复制关系并最终克隆它们。

<?php
$clone = $model->replicate();
$clone->push();

foreach ($model->getRelations() as $relation => $entries){
    foreach($entries as $entry){
        $e = $entry->replicate();
            if ($e->push()){
                $clone->{$relation}()->save($e);

                // @todo Go further down
            }
        }
    }
}
?>

问题是这对于第一级的关系非常有效;但是,如果存在其他嵌套关系,则不会复制/克隆它们。什么是在关系中进一步遍历并将它们全部复制的最有效方式?

由于

1 个答案:

答案 0 :(得分:2)

我会覆盖模型上的replicate()方法以复制孩子。然后我将该功能提取到特征中,并将特征应用于所有模型。类似的东西:

trait DeepReplicates {
    public function replicate(){
        $copy = parent::replicate();
        $copy->push();

        foreach ($model->getRelations() as $relation => $entries){
            foreach($entries as $entry){
                $e = $entry->replicate();
                if ($e->push()){
                    $clone->{$relation}()->save($e);
                }
            }
        }
    }
}

然后应用该特征,每个被复制的模型也将复制其特征。自己的孩子,递归地下线。你必须确保你不会在循环中结束,但它应该有效。

您甚至可以为每个模型添加一个变量,以指定应该复制的子模型数组。这样可以避免可能的逻辑循环。