Alimon Karim
Alimon Karim

Reputation: 4469

How to save a record with associated data

In my application there are 3 types of information:

A user should fill out all of the data before it is saved to the database.

What I've tried so far is below, but something is wrong with the transactions as for example BrokerInfo records are being created without BrokerBank records. What is the correct way to store everything or nothing?

public function add() {
        if ($this->request->is('post')) {
            $this->BrokerInfo->begin();
            $this->BrokerInfo->create();
            $this->request->data['BrokerInfo']['id'] = String::uuid();
            $this->request->data['BrokerInfo']['account_status_id'] = 1;
            $this->request->data['BrokerInfo']['db_status_id'] = 1;
            if ($this->BrokerInfo->save($this->request->data)) {

                $this->BrokerBank->begin();
                $this->BrokerBank->create();
                $this->request->data['BrokerBank']['broker_info_id'] = $this->request->data['BrokerInfo']['id'];
                if($this->BrokerBank->save($this->request->data))
                {
                    $this->BrokerDocument->begin();
                    $this->BrokerDocument->create();
                    if($this->BrokerDocument->save($this->request->data))
                    {
                        $this->BrokerInfo->commit();
                        $this->BrokerBank->commit();
                        $this->BrokerDocument->commit();

                        $this->Session->setFlash(__('The Broker information has been saved'), 'flash_success');
                        $this->redirect(array('action' => 'index'));
                    }
                    else
                    {
                        $this->BrokerInfo->rollback();
                        $this->BrokerBank->rollback();
                        $this->BrokerDocument->rollback();
                        $this->Session->setFlash(__('The customer information could not be saved. Please, try again.'), 'flash_fail');
                    }
                }
                else 
                {
                    $this->BrokerInfo->rollback();
                    $this->BrokerBank->rollback();
                    $this->Session->setFlash(__('The customer information could not be saved. Please, try again.'), 'flash_fail');
                }

            }
            else 
            {
                $this->BrokerInfo->rollback();
                $this->Session->setFlash(__('The customer information could not be saved. Please, try again.'), 'flash_fail');
            }
        }

Upvotes: 1

Views: 111

Answers (1)

AD7six
AD7six

Reputation: 66208

Use saveAssociated

The code in the question is a user-land implementation of something which already exists: saveAssociated

Model::saveAssociated(array $data = null, array $options = array())

Method used to save multiple model associations at once.

Using saveAssociated the code in the question is no more than:

public function add() {
    if (!$this->request->is('post')) {
        return;
    }

    $this->BrokerInfo->create();
    $this->request->data['BrokerInfo']['account_status_id'] = 1;
    $this->request->data['BrokerInfo']['db_status_id'] = 1;
    if ($this->BrokerInfo->saveAssociated($this->request->data)) {
        $this->Session->setFlash(...);
        return $this->redirect(array('action' => 'index'));
    }

    $this->Session->setFlash(...);
}

Note that it's not necessary to specify the uuid (use $model->id after save to refer to the new id), and the current hard coded defaults would be better placed in a model beforeSave method unless their values are controller-logic dependent.

Upvotes: 1

Related Questions