【问题标题】:Clone entity and all related entities in CakePHP 3CakePHP 3 中的克隆实体和所有相关实体
【发布时间】:2015-11-10 15:23:49
【问题描述】:

在我的 CakePHP 3 应用程序中,我有一个稍微复杂的实体树,我需要克隆和保存它。

结构的根是一个问卷调查,一个问卷调查有很多问题,每个问题有很多字段,等等(它更深入)。现在我希望用户能够通过复制旧问卷来定义新问卷。然后他们可以改变他们需要的任何东西。

我可以通过使用$questionnaire->$this->Questionnaires->get($id) 和适当的包含 字段来获得我需要复制的内容的转储。有没有一种聪明的方法可以将其保存为一堆新实体,同时保留它们之间的数据和结构?

【问题讨论】:

    标签: php cakephp cakephp-3.0


    【解决方案1】:

    我认为最好的方法是遵循工作流程:

    1. 获取要克隆的对象
    2. 浏览集合并删除所有 ID
    3. 转换为数组并在$this->Questionnaires->newEntity($arrayData, ['associated' => ['Questions', '...']]);中使用
    4. 现在保存新实体以及您要保留的所有相关数据

    AFAIK 在 Cake 3 中没有“更智能”的方法来克隆具有关联的实体 :-)

    【讨论】:

    • 这里转换为数组并返回实体的意义何在?假设要克隆的对象已经是一个实体,那么这种双重转换的结果会有什么不同吗?
    • 因为你需要它作为数组数据在newEntity() (api.cakephp.org/3.1/class-Cake.ORM.Table.html#_newEntity) 值得尝试克隆实体,删除ID,然后尝试在save() 中使用它 - 我'不确定这是否会将它保存为一个新实体,但它实际上可以做到这一点.. (api.cakephp.org/3.1/class-Cake.ORM.Table.html#_save)
    • 是的,我认为如果您删除所有 ID 并调用 isNew(true),您将获得与转换为数组并返回相同的结果。正在构建一个将递归和通用地执行此操作的函数(基于模型的关联),但尚未经过全面测试。
    • 啊哈!我什至不确定除了删除 ID 之外是否还有必要......
    【解决方案2】:

    您也可以使用this plugin。您只需配置行为,它会为您提供其他功能,例如设置默认值或将文本附加到某些字段。

    【讨论】:

      【解决方案3】:

      使用 EntityInteface toArray() 获取其所有字段:

      $newEtity = $someTable->newEntity($oldEtity->toArray());
      unset($newDevice->created);
      unset($newDevice->id);
      $someTable->save($newEntity);
      

      【讨论】:

        【解决方案4】:
        $original = $this->Table->get($id)->toArray();
        $copy = $this->Table->newEntity();
        $copy = $this->Table->patchEntity($copy, $original);
        
        unset($copy['id']);
        // Unset or modify all others what you need
        
        $this->Table->save($copy);
        

        像这样完美地工作:)

        【讨论】:

          【解决方案5】:

          当我需要类似的东西时,我是这样做的(适用于问卷示例):

          // load the models
          $this->loadModel('Questionnaire');
          $this->loadModel('Questions');
          // get the questions to questionnaire association - will need the PK name
          $qAssoc = $this->{'Questions'}->associations()->get('Questionnaire');
          // get the existing entity to copy
          $existingEntity = $this->{'Questionnaire'}->get($id, [
              'contain' => ['Questions'],
          ]);
          // clean up the existing entity
          $existingEntity->unsetProperty($this->{'Questionnaire'}->getPrimaryKey());
          $existingEntity->unsetProperty('created');
          $existingEntity->unsetProperty('modified');
          // clean up the associated records of the existing entity
          foreach ($existingEntity->questions as &$q) {
              $q->unsetProperty($this->{'Questions'}->getPrimaryKey());
              $q->unsetProperty($qAssoc->getForeignKey());
          }
          // create a new entity and patch it with source data
          $newEntity = $this->{'Questionnaire'}->patchEntity(
                  $this->{'Questionnaire'}->newEntity(),
                  $existingEntity->toArray()
          );
          // save the new entity
          $result = $this->{'Questionnaire'}->save($existingEntity);
          

          参考资料:

          【讨论】:

            猜你喜欢
            • 2020-01-09
            • 2018-10-04
            • 1970-01-01
            • 2014-06-16
            • 2016-05-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多