User Tools

Site Tools


php:embededid

How to insert ids in embedded forms for new objects

13.01.2010

In symfony it's very easy to embed forms for different related objects. But sometimes you want to update the ids in related tables after you insert new records in the main table. To do this, you can override the save() method to get the new id and then update the related table, but also you can apply a very simple procedure described next.

We have two tables SnUser and SnOther. The structure taken from schema.yml (using Doctrine) is:

SnUser:
    columns:
        name: { type: string(100) }
        age: { type: integer(1) }
        level_id: integer
    relations:
        SnOther: { local: id, foreign: user_id }
 
SnOther:
    columns:
        user_id: integer
        spinach: string(10)
        carrots: integer(1)
    relations:
        SnUser:
            local: user_id
            foreign: id
            onDelete: CASCADE
            foreignType: one

This is a one-to-one relationship. To display also SnOther in the SnUserForm we use normally such thing:

SnUserForm.class.php

// SnUserForm.class.php
$this->embedForm('altceva', new SnOtherForm());

When you save, a new record for SnUser will be entered into the tables and of course, the embedded form also, resulting in a related SnOther record. Except for the user_id field which will be NULL, because the id for SnUser is obtained after database saving (autoincrement).

What we need to do it to linked these two objects and this is how we do it:

lib/form/doctrine/SnUserForm.class.php

// lib/form/doctrine/SnUserForm.class.php
class SnUserForm extends BaseSnUserForm
{
  public function configure() {
      ...
      // return the current SnOther object for this form
      // if none, create a new one and set it to the form
      $otherObj = $this->getObject()->getSnOther();
      if( is_null($otherObj) ) {
          $otherObj = new SnOther();
          $this->getObject()->setSnOther($otherObj);
      }
 
    // use it to initialize default values for SnOtherForm
    // this way, we link this newly created form to the main one (SnUserForm)
    $formOther = new SnOtherForm($otherObj);
 
    // important, otherwise it wont save
    unset($formAlt['user_id']);
 
    // regular embed 
    $this->embedForm('other', $formOther);
  }
...
}

When you save the SnUser object, the record related will be automatically updated with the user_id. Great, huh? :)


Ok, now for one-to-many relationship case. If you try to apply the same technique, you'll discover that $this→getObject()→getSnOther() will return a Doctrine_Collection and not an Object, resulting in an error when you try to construct the Form. The good procedure is this:

        ...
        $otherfrm = new SnOtherForm();
        $otherfrm->getObject()->setUserId($this->getObject())
        ...
        $this->embedForm('other', $otherfrm);

php/embededid.txt · Last modified: 2013/03/16 17:40 (external edit)