0
votes

I am working in a Symfony 1.4 project with Propel 1.4.2.

I have 2 related tables. workshop and trainers which is a many to many relation mapped by a join table (workshop_trainers) which contains the workshop_id and the trainer_id).

In my Workshop Form I have a select box for adding the trainers to the workshop. The problem is when the workshop is new (Create) I get an error:

Cannot add or update a child row: a foreign key constraint fails

This happens because, when saving the workshop_trainers relation the workshop_id field is null. Isn´t Propel intelligent enough to know that there is a relation between the tables and save the base object first? What I am doing wrong?

My trainer list widget.

$this->widgetSchema['workshop_trainer_list'] = new sfWidgetFormChoice(array( 'choices' => $trainers, 'multiple' => true, ));

Thanks for your help.

1
Not sure if this is helpful, but I remember there being some problems with Propel and many-to-many relationships. Read this post (point 3 particularly) itsmajax.com/2011/01/29/…. This is the bug it tries to work around trac.symfony-project.org/ticket/5867. The post is worth a read either way...antony

1 Answers

0
votes

This is not fixing the problem but that's the easiest practical solution to this problem:

In the form, simply deactivate the workshop_trainer_list field if the object is a new one (doesn't have an ID yet).

Something like:

if ($this->getObject()->isNew())
{
  $this->offsetUnset('workshop_trainer_list'); // not sure of that method name
}

A better solution is to update the doSave method to have the ID first, something like this:

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

    // retrieve the value of workshop_trainer_list here and remove it from the form
    $trainers = ...
    $this->offsetUnset('workshop_trainer_list');

    // save without it
    parent::doSave($con);

    // add it back
    $this->getObject()->set...

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