1

I am using Datamapper ORM 1.8.2.1 with CodeIgniter 2.1.0 and I have trouble accessing newly added related objects from within a parent.

I have a parent class like this:

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

and a child class like this:

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

In the user code, I instantiate this parent and add a few child objects:

$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);

// ...

When I then count immediately after the added child objects, I get 0 :

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

... whereas taking a look in the database table shows that the parent record has been added, all the child records have been added, and they are correctly related with the parent record.

By the way, when I then try this workaround, I get the correct number of child rows:

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

So what might be wrong with my code above ?

Wesley Murch
  • 101,186
  • 37
  • 194
  • 228
IhariR
  • 21
  • 4
  • It so happens that I override the save() method for business rules enforcement reasons. Without knowing if that has something to to with the problem, a workaround goes like this: public function save($prmObject = "", $prmRelatedField = "") { ... $this->get(); }. The get() seems to force a reload on the object tree and makes the child objects available. – IhariR Mar 21 '12 at 20:30
  • Yet another evolution of this workaround: If I immediately one after the other instantiate two new objects and call save() on them, Datamapper ORM seems to be confused and restitutes a one and same id for both. However, when you peek into the database, you would see two different ids i.e. the save is done correctly but the two new objects aren't correctly populated. To work around this, the previous get() code becomes: **$this->where("id", $this->id)->get();** – IhariR Mar 31 '12 at 20:40
  • My guess is that something is cached somewhere - is your database caching query results? – swatkins Jun 26 '12 at 14:18

1 Answers1

0

In my experience, Datamapper doesn't make related objects accessible immediately after a save. This includes displaying the properties of a related object; to follow on from your example, the following code will not display the ID of the $vrt object:

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

However, if you redirect, or reload the page, and then reload the $li object, all related items will be available as expected.

If you really need to have related items immediately available, you can create a new related object and load it based on the _id value, as you suggest. Something like:

$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;

(Obviously the above code would be unnecessary, as you already know the ID of the $vrt object, but this is the general principle).

Incidentally, regarding the note in your comment about Datamapper using the same ID for two new objects, I'd avoid using the same variable name for both the objects; this will be unreliable in my experience. Instead, use different variable names, or (if this is unavoidable) take a look at the "Clear" method: http://datamapper.wanwizard.eu/pages/utility.html#clear .

sevenpointsix
  • 394
  • 5
  • 4