1
votes

I used to play with embedded relation/forms with Symfony 1.4 but I've a problem I can't resolve.

What I want to do is :

  • When a user create a new Event, I embed the relation/forms for the destination and the departure
  • The user could be able to select an existing city via the sfWidgetFormJQueryAutocompleter and if the city do not exist in the DB, the new city is inserted and the association between the departure/destination and the Event is made.

I tried to simply embed relation like that in my city form

public function configure() {
  parent::configure(); 
  unset($this['city_departure_id']);
  unset($this['city_destination_id']);

  $this->embedRelation('Departure', new MyCityForm($this->getObject()->getDeparture()));
  $this->embedRelation('Destination', new MyCityForm($this->getObject()->getDestination()));
  ...
}

If there is a new city, it works but when i get back an existing city (id, name and country are correclty populated), it fail by saying Id Invalid.

What I tried to do is to correct my default validator for the id and convert the base validator (sfValdidatorChoice) into

$this->setValidator('id', new sfValidatorPass(array('required' => false)));

It pass the validation but fail because Symfony try to create a new object with exactly same value.

Now I tried to override the save method for the City into something like that :

public function save(Doctrine_Connection $con = null) {

        if ($this->isNew() && $this->getId() != "") {

            return $this;
        }
        return parent::save($con);
    }

Now it create cities when needed but not when they're already exist.

My new problem is that fail on the event insertion. It throw a new Exception saying:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'city_destination_id' cannot be null

(in this case, the city_departure was a new one and the destination an existing one)

Here is my schema.yml

Event:
  connection: doctrine
  tableName: sortie
  columns:
    id:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: true
      autoincrement: true
    description:
      type: string(255)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    start_date:
      type: date(25)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    city_departure_id:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    city_destination_id:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
  relations:
    Departure:
      local: city_departure__id
      foreign: id
      class: City
      type: one
    Destination:
      class: City
      local: city_destination_id
      foreign: id
      type: one
City:
  connection: doctrine
  tableName: localite
  columns:
    id:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: true
      autoincrement: true
    name:
      type: string(100)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    country:
      type: string(100)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
  relations:
    Departures:
      local: id
      foreign: localite_depart_id
      type: many
    Destinations:
      class: Sortie
      local: id
      foreign: localite_destination_id
      type: many
1

1 Answers

1
votes

Ok after a long day I found a solution... But I'm not sure it's the most correct solution...

I override the doSave method in my form. After the updateObject call, I check if ids are present in values or not. It seems to work...

protected function doSave($con = null) {
    if (null === $con)
    {
      $con = $this->getConnection();
    }

    $this->updateObject();

    $v = $this->getValues();
    if (isset($v['Departure']['id']))
        $this->getObject()->setCityDepartureId($v['Departure']['id']);
    if (isset($v['Destination']['id']))
        $this->getObject()->setCityDestinationId($v['Destination']['id']);

    $this->getObject()->save($con);

    // embedded forms
    $this->saveEmbeddedForms($con);
}