Скопируйте объект Doctrine со всеми связями - PullRequest
3 голосов
/ 01 марта 2010

Я хочу скопировать запись со всеми его связями.

Я пытаюсь:

$o = Doctrine::getTable('Table')->Find(x); 
$copy = $object->copy();
$relations = $o->getRelations();

foreach ($relations as $name => $relation) {
  $copy->$relation = $object->$relation->copy();
} 

$copy->save();

Этот код не работает, но я думаю, что он в пути.

Ответы [ 5 ]

5 голосов
/ 04 марта 2010

Мне никогда не удавалось заставить функцию глубокого копирования работать правильно.

Я вручную закодировал функцию глубокого копирования для одной из моих моделей, как эта

public function copyAndSave ()
{
    $filters = array('id', 'created');

    $survey = $this->copy();

    $survey->Survey_Entries = new Doctrine_Collection("Survey_Model_Entry");
    $survey->Assignment_Assignments = new Doctrine_Collection("Assignment_Model_Assignment");
    $survey->Survey_Questions = new Doctrine_Collection("Survey_Model_Question");

    $survey->save();

    foreach ($this->Survey_Questions as $question)
    {
        $answers = $question->Survey_Answers;
        $newQuestion = $question->copy();
        $newQuestion->survey_surveys_id = $survey->id;
        $newQuestion->save();
        $newAnswers = new Doctrine_Collection("Survey_Model_Answer");

        foreach($answers as $answer)
        {
            $answer = $answer->copy();
            $answer->save();
            $answer->survey_questions_id = $newQuestion->id;
            $newAnswers->add($answer);
        }
        $newQuestion->Survey_Answers = $newAnswers;

        $survey->Survey_Questions->add($newQuestion);
    }
    return $survey->save();
}
3 голосов
/ 02 марта 2010

Вы можете прочитать о copy() здесь . Требуется необязательный параметр $deep:

$ глубокий
дублировать ли объекты, на которые нацелены отношения

Итак

$copy = $object->copy(true);

должен это сделать.

2 голосов
/ 19 апреля 2010

Извините, если я воскрешаю эту тему ...

Я недавно оказался в поиске решения, где мне нужно было скопировать запись и сохранить ссылки на оригинал. Глубокая копия $record->copy(true) копирует ссылки, что мне не понравилось. Это было мое решение:

$record = Doctrine_Core::getTable('Foo')->find(1);
$copy = $record->copy();

foreach($record->getTable()->getRelations() as $relation) {
    if ($relation instanceof Doctrine_Relation_Association) {
        $ids = array();

        foreach ($relation->fetchRelatedFor($record) as $r) {    
            $ids[] = $r->getId();
        }

        $copy->link($relation->getAlias(), $ids);
    }
}

if ($copy->isValid()) {
    $copy->save();
}

Надеюсь, это поможет:)

0 голосов
/ 07 июля 2010

Я использую Symfony1.4.1 и использует Doctrine 1.2.1 (я думаю).

Я пытался создать функцию, которая выполняла все вышеперечисленное самостоятельно, когда нашел такую, которая уже существует.

Попробуйте это в любой функции и посмотрите на результаты:

  $tmp=$this->toArray(TRUE);
  var_dump($tmp);
  $this->refreshRelated();
  $tmp=$this->toArray();
  var_dump($tmp);
  $tmp=$this->toArray(TRUE);
  var_dump($tmp);
  exit();

Я собираюсь попробовать две разные вещи:

A / put $ this-> refreshRelated () в конструктор всех моих модельных объектов.B / написать функцию, которая принимает массив, изображающий граф объекта, который я хочу заполнить.Вызов функции refereshRelatedGraph ($ objectGraphArray).С правильной структурой массива (имеющей все соответствующие имена отношений на каждом уровне) я мог бы контролировать, какие отношения заполняются, а какие нет.Одним из способов использования этого является заполнение только детей, а не родительских отношений.Другое для случая, когда ERD / Schema / ObjectGraph имеет элемент, который «принадлежит» более чем одному объекту (многие ко многим, другие особые обстоятельства, которые у меня есть), я мог бы контролировать, какая сторона отношений предварительно (не ленивая)) загружено.

0 голосов
/ 15 апреля 2010

Я так и сделал, но нужно исправить.

    $table = $entidade->getTable();
    $relations = $table->getRelations();
    foreach($relations as $relation => $data) {
        try {
            $entity->loadReference($relation);
        } catch(Exception $e) {
            die($e->getMessage());
        }
    }
...