tags:

views:

414

answers:

1

Hi, I have a table that is related to another. Is it possible to use the auto incremented Id of table one as the foreign key of table two in one statement, rather than using lastInsertId and performing a separate save on each table? Any advice appreciated. Thanks.

A: 

From what I understand you have two classes, let's call them ClassA and ClassB, where ClassA has a relation to ClassB? As in

class ClassA extends Doctrine_Record
{
  public function setTableDefinition()
  {
    $this->hasColumn('id', 'integer', 4, array('type' => 'integer', 'autoincrement' => true, 'primary' => true, 'length' => 4);
    $this->hasColumn('classBId', 'integer', 4, array('type' => 'integer', 'length' => 4);
  }

  public funtion setUp()
  {
    $this->hasOne('ClassB as classB', array('local' => 'classBId', 'foreign' => 'id',  'onDelete' => 'CASCADE', 'onUpdate' => 'CASCADE'));
  }
}

and

class ClassB extends Doctrine_Record
{
  public function setTableDefinition()
  {
    $this->hasColumn('id', 'integer', 4, array('type' => 'integer', 'autoincrement' => true, 'primary' => true, 'length' => 4);
  }

  public funtion setUp()
  {
    $this->hasMany('ClassA as classAs', array('local' => 'id', 'foreign' => 'classBId'));
  }
}

Supposing you're doing something like this:

$classAInstance = new ClassA;
$classBInstance = new ClassB;

$classAInstance->classB = $classBInstance;

$classB->save();
$classA->save();

Because this is necessarily translated into two separate INSERT queries, it is not possible to do both insertions in a single SQL query. However, there is no need to muck around with lastInsertId, by setting the related property instead of setting $classA->classBId directly, Doctrine will keep track of the ids.

Magnus Nordlander
Furthermore, if you had just called $classA->save();, doctrine would see that classA's classB foreign reference record was dirty and would save that record first, then take the id and store it in classBId before saving classA. So for the most part, as long as your records are all well defined, you can make a single ->save() call from the top of your 'tree'.
Kevin