2012-03-21 1 views
1

Я использую Datamapper ORM 1.8.2.1 с CodeIgniter 2.1.0, и у меня возникают проблемы с доступом к недавно добавленным связанным объектам из родителя.Как получить доступ к вновь сохраненным связанным объектам в Datamapper ORM

У меня есть родительский класс вроде этого:

class Virement extends DataMapper 
{ 
    var $has_many = array("lignevirement"); 
    // ... 
} 

и класс ребенка, как это:

class LigneVirement extends DataMapper 
{ 
    var $has_one = array("virement"); 
    // ... 
} 

В пользовательском коде, я создаю экземпляр этого родителя и добавить несколько дочерних объектов:

$vrt = new Virement;  // and do some inits on properties. 
$vrt->save(); 

$lili = new LigneVirement; // do some inits also on properties. 
$lili->save(); 
$vrt->save($lili); 

$lili = new LigneVirement; // do some inits also on properties. 
$lili->save(); 
$vrt->save($lili); 

// ... 

Когда я потом подсчитываю сразу после добавления дочерних объектов, я получаю 0:

echo $vrt->lignevirement->count(); 

... а взглянуть в таблицу базы данных показывает, что родительская запись была добавлена ​​, все дочерние записи были добавлены, и они правильно, связанные с родительской записью ,

Кстати, когда я затем попробовать этот обходной путь, я получаю правильное количество дочерних строк:

$vrt = new Virement($vrt->id); 

Так что может быть не так с моим кодом выше?

+0

Так получилось, что я переопределяю метод save() для принудительного использования бизнес-правил. Не зная, есть ли у этого проблемы с этой проблемой, обходной путь выглядит следующим образом: public function save ($ prmObject = "", $ prmRelatedField = "") {... $ this-> get(); }. Кажется, что get() заставляет перезагружать дерево объектов и делает дочерние объекты доступными. – IhariR

+0

Еще одна эволюция этого обходного пути: если я сразу один за другим создаю два новых объекта и вызову save() на них, Datamapper ORM, похоже, запутался и заменит один и тот же идентификатор для обоих. Однако, когда вы заглядываете в базу данных, вы увидите два разных идентификатора, т. Е.сохранение выполняется правильно, но два новых объекта неправильно заполнены. Чтобы обойти это, предыдущий код get() становится: ** $ this-> где («id», $ this-> id) -> get(); ** – IhariR

+0

Я предполагаю, что что-то кэшировано где-то - это результаты запроса кэширования базы данных? – swatkins

ответ

0

По моему опыту, Datamapper не делает связанные объекты доступными сразу после сохранения. Это включает отображение свойств связанного объекта; следовать дальше от вашего примера, следующий код будет не отобразить идентификатор объекта $ VRT:

$vrt = new Virement; 
$vrt->get_by_id(1); 
$li = new LigneVirement; 
$li->save($vrt); 
echo $li->vrt->id; 

Однако, если вы перенаправлять или перезагрузить страницу, а затем перезагрузить объект $ Ли, все связанные элементы будут доступны, как ожидалось.

Если вам действительно нужно иметь связанные предметы сразу же, вы можете создать новый связанный объект и загрузить его на основе значения _id, как вы предлагаете. Что-то вроде:

$vrt = new Virement; 
$vrt->get_by_id(1); 
$li = new LigneVirement; 
$li->save($vrt); 
$vrt_refresh = new Virement; 
$vrt_refresh->get_by_id($li->vrt_id); 
echo $vrt_refresh->id; 

(Очевидно, что приведенный выше код будет излишним, так как вы уже знаете идентификатор объекта $ VRT, но это общий принцип).

Кстати, что касается примечания в вашем комментарии о Datamapper с использованием того же идентификатора для двух новых объектов, я бы не использовал одно и то же имя переменной для обоих объектов; это будет ненадежным по моему опыту. Вместо этого используйте разные имена переменных или (если это неизбежно) взгляните на метод «Очистить»: http://datamapper.wanwizard.eu/pages/utility.html#clear.