phpformssymfony1propel

saving embedded Propel symfony form for one-to-one relationship


I have a pair of tables that have a one-to-one relationship.

I have a complaint form that needs to embed a person form inside of that, the relevant schema is below:

  complaint:
    id:                            ~
    created_at:                    ~
    updated_at:                    ~
    complainant_id:                { type: integer, foreignTable: person_data, foreignReference: id, onDelete: setnull }
    status:                        { type: tinyint, default: 1 }
    complaint_title:               { type: varchar(64) } 
    complaint_number:              { type: varchar(16) } 
    recipient:                     { type: varchar(128) }

  person_data:
    id:                            ~
    created_at:                    ~
    updated_at:                    ~
    company_name:                  { type: varchar(64) }
    first_name:                    { type: varchar(64) }
    last_name:                     { type: varchar(64) }
    email:                         { type: varchar(128) }

I am able to successfully save both objects to the database but the main complaint object is not being updated with the complainant_id of the person_data row.

Does anyone know why this isn't working correctly and how to force it to update the complaint object correctly?

I am using symfony 1.4.13, Propel 1.6.3.

UPDATE:

Here is the code for the embedded form:

<?php
    public function configure()
    {
        $use_fields = array();

        // ...other fields added...


        $sub_form   = new PersonDataForm(array(), array());
        $this->embedForm('complainant', $sub_form);
        array_push($use_fields, 'complainant');

        $this->useFields($use_fields);
    }

Solution

  • I've found a solution to this problem.

    Override the saveEmbeddedForms method in the form class.

    Updating the main object occurs after the saving of the embedded forms so the ids are available to update the main object.

    public function saveEmbeddedForms($con = null, $forms = null) 
    {
    
        // save the embedded forms
        parent::saveEmbeddedForms($con, $forms);
    
        // loop through all embedded forms and update the main object with their ids
        foreach($this->getEmbeddedForms() as $name => $embedded_form)
        {
            switch($name)
            {
                case 'recipient':
                    // criteria to determine if the sub-object should be saved or not
                    if($embedded_form->getObject()->getFirstName() == '' && $embedded_form->getObject()->getLastName() == '')
                    {
                        $embedded_form->getObject()->delete();
                        $this->getObject()->setRecipientId(null);
                        $this->getObject()->save();
                    }
                    else
                        $this->getObject()->setRecipientId($embedded_form->getObject()->getId());
                    break;
                case 'complainant':
                    if($embedded_form->getObject()->getFirstName() == '' && $embedded_form->getObject()->getLastName() == '')
                    {
                        $embedded_form->getObject()->delete();
                        $this->getObject()->setComplainantId(null);
                        $this->getObject()->save();
                    }
                    else
                    {
                        $this->getObject()->setComplainantId($embedded_form->getObject()->getId());
                    }
                    break;
                default:
                    break;
            }
        }
    
        // save the main object with the new sub-object keys set
        $this->getObject()->save();         
    }
    

    Unfortunately there is nowhere that I can find on the internet with this explanation. So here it is for those that come after me.