Monday, November 17, 2014

Problems with saveAssociated

Hello,

I have problems saving associated data with CakePHP 2.5.5. The data is only saved partially - the members table and the contracts table are updated, but in the contracts table are created 4 rows for 1 member instead of 1 row. The deeper levels are not saved, whether or not setting the recursive level or using the "deep"-switch. The validation only works for Member and Contract models, but there is also the problem that "contractperiod" is allways validated, even when there is no validation rule inside Contract-Model.

Regarding to the documentation all should be easy...just use saveAssociated and store the request data nested...but perhaps I did not understand it properly.

Here are my Models, the MemberController, the View and a dump of the request data before saving the Data. I hope you can tell me what I have done wrong...


Best regards,

LowFrequencyLast


Member.php
<?php
App::uses('AppModel', 'Model');
/**
 * Member Model
 *
 * @property Contract $Contract
 */

class Member extends AppModel {


   
//The Associations below have been created with all possible keys, those that are not needed can be removed

/**
 * hasMany associations
 *
 * @var array
 */

   
public $hasMany = array(
       
'Contract' => array(
           
'className' => 'Contract',
           
'foreignKey' => 'member_id',
           
'dependent' => false,
           
'conditions' => '',
           
'fields' => '',
           
'order' => '',
           
'limit' => '',
           
'offset' => '',
           
'exclusive' => '',
           
'finderQuery' => '',
           
'counterQuery' => ''
       
)
   
);

public $validate = array (
       
'firstname' => array (
       
'rule' => 'notEmpty',
       
'message' => ''
   
),
       
'lastname' => array (
       
'rule' => 'notEmpty',
       
'message' => ''
   
)
);

}


Contract.php
<?php
App::uses('AppModel', 'Model');
/**
 * Contract Model
 *
 * @property Member $Member
 * @property Contractdetail $Contractdetail
 * @property Grant $Grant
 */

class Contract extends AppModel {


   
//The Associations below have been created with all possible keys, those that are not needed can be removed

/**
 * belongsTo associations
 *
 * @var array
 */

   
public $belongsTo = array(
       
'Member' => array(
           
'className' => 'Member',
           
'foreignKey' => 'member_id',
           
'conditions' => '',
           
'fields' => '',
           
'order' => ''
       
)
   
);

/**
 * hasMany associations
 *
 * @var array
 */

   
public $hasMany = array(
       
'Contractdetail' => array(
           
'className' => 'Contractdetail',
           
'foreignKey' => 'contract_id',
           
'dependent' => false,
           
'conditions' => '',
           
'fields' => '',
           
'order' => '',
           
'limit' => '',
           
'offset' => '',
           
'exclusive' => '',
           
'finderQuery' => '',
           
'counterQuery' => ''
       
),
       
'Grant' => array(
           
'className' => 'Grant',
           
'foreignKey' => 'contract_id',
           
'dependent' => false,
           
'conditions' => '',
           
'fields' => '',
           
'order' => '',
           
'limit' => '',
           
'offset' => '',
           
'exclusive' => '',
           
'finderQuery' => '',
           
'counterQuery' => ''
       
)
   
);

public $validate = array (
       
'contractbegin' => array (
       
'rule' => 'notEmpty',
       
'message' => ''
   
),
       
'contractperiod' => array (
       
'rule' => 'notEmpty',
       
'message' => ''
   
)
);

}


Contractdetail.php
<?php
App::uses('AppModel', 'Model');
/**
 * Contractdetail Model
 *
 * @property Contract $Contract
 */

class Contractdetail extends AppModel {


   
//The Associations below have been created with all possible keys, those that are not needed can be removed

/**
 * belongsTo associations
 *
 * @var array
 */

   
public $belongsTo = array(
       
'Contract' => array(
           
'className' => 'Contract',
           
'foreignKey' => 'contract_id',
           
'conditions' => '',
           
'fields' => '',
           
'order' => ''
       
)
   
);

public $validate = array (
       
'memberfee' => array (
       
'rule' => 'notEmpty',
       
'message' => ''
   
)
);

}


Grant.php
<?php
App::uses('AppModel', 'Model');
/**
 * Grant Model
 *
 * @property Contract $Contract
 * @property Grantedcourse $Grantedcourse
 */

class Grant extends AppModel {


   
//The Associations below have been created with all possible keys, those that are not needed can be removed

/**
 * belongsTo associations
 *
 * @var array
 */

   
public $belongsTo = array(
       
'Contract' => array(
           
'className' => 'Contract',
           
'foreignKey' => 'contract_id',
           
'conditions' => '',
           
'fields' => '',
           
'order' => ''
       
)
   
);

/**
 * hasMany associations
 *
 * @var array
 */

   
public $hasMany = array(
       
'Grantedcourse' => array(
           
'className' => 'Grantedcourse',
           
'foreignKey' => 'grant_id',
           
'dependent' => false,
           
'conditions' => '',
           
'fields' => '',
           
'order' => '',
           
'limit' => '',
           
'offset' => '',
           
'exclusive' => '',
           
'finderQuery' => '',
           
'counterQuery' => ''
       
)
   
);

public $validate = array (
       
'grantlevel' => array (
       
'rule' => 'notEmpty',
       
'message' => ''
   
)
);    

}


Grantedcourse.php
<?php
App::uses('AppModel', 'Model');
/**
 * Grantedcourse Model
 *
 * @property Grant $Grant
 */

class Grantedcourse extends AppModel {


   
//The Associations below have been created with all possible keys, those that are not needed can be removed

/**
 * belongsTo associations
 *
 * @var array
 */

   
public $belongsTo = array(
       
'Grant' => array(
           
'className' => 'Grant',
           
'foreignKey' => 'grant_id',
           
'conditions' => '',
           
'fields' => '',
           
'order' => ''
       
)
   
);

public $validate = array (
       
'coursename' => array (
       
'rule' => 'notEmpty',
       
'message' => ''
   
)
);    

}


MembersController.php
<?php
App::uses('AppController', 'Controller');
/**
 * Members Controller
 *
 * @property Member $Member
 * @property PaginatorComponent $Paginator
 */

class MembersController extends AppController {

/**
 * Components
 *
 * @var array
 */

   
public $components = array('Paginator');

/**
 * index method
 *
 * @return void
 */

   
public function index() {
        $this
->Member->recursive = 0;
        $this
->set('members', $this->Paginator->paginate());
   
}

/**
 * add method
 *
 * @return void
 */

   
public function add() {
    $this
->Member->recursive = 4;
       
if ($this->request->is('post')) {
       
CakeLog::write('debug', 'myArray'.print_r($this->request->data, true));
            $this
->Member->create();
           
if ($this->Member->saveAssociated($this->request->data, array('deep' => true))) {
                $this
->Session->setFlash(__('The member has been saved.'));
               
return $this->redirect(array('action' => 'index'));
           
} else {
                $this
->Session->setFlash(__('The member could not be saved. Please, try again.'));
           
}
       
}
   
}


}


add.ctp
<div class="members form">
<?php echo $this->Form->create('Member'); ?>
<table>
   
<tr>
       
<td>
           
<?php echo $this->Form->input('Member.firstname', array('label' => 'Firstname:','required'=>'false', 'id'=>'id_firstname'));?>
       
</td>
       
<td>
           
<?php echo $this->Form->input('Member.lastname', array('label' => 'Lastname:','required'=>'false', 'id'=>'id_lastname'));?>
       
</td>
   
</tr>
   
<tr>
       
<td>
           
<?php echo $this->Form->input('Member.Contract.contractbegin', array('label' => 'Begin of contract:','required'=>'false', 'id'=>'id_contractbegin'));?>
       
</td>
       
<td>
           
<?php echo $this->Form->input('Member.Contract.contractperiod', array('label' => 'Contract period:','required'=>'false', 'id'=>'id_contractperiod'));?>
       
</td>
   
</tr>
   
<tr>
       
<td>
           
<?php echo $this->Form->input('Member.Contract.Contractdetail.memberfee', array('label' => 'Memberfee:','required'=>'false', 'id'=>'id_memberfee'));?>
       
</td>
       
<td>
           
<?php echo $this->Form->input('Member.Contract.Grant.grantlevel', array('label' => 'Grant level:','required'=>'false', 'id'=>'id_grantlevel'));?>
       
</td>
   
</tr>
   
<tr>
       
<td>
           
<?php echo $this->Form->input('Member.Contract.Grant.Grantedcourse.0.coursename', array('label' => '1. Course:','required'=>'false', 'id'=>'id_coursename1'));?>
       
</td>
       
<td>
           
<?php echo $this->Form->input('Member.Contract.Grant.Grantedcourse.1.coursename', array('label' => '2. Course:','required'=>'false', 'id'=>'id_coursename2'));?>
       
</td>
   
</tr>
</table>
<?php echo $this->Form->submit(__('Create member...'), array('name' => 'create')); ?>
</div>



$request->data
(
   
[create] => Create member...
   
[Member] => Array
       
(
           
[firstname] => James
           
[lastname] => Last
           
[Contract] => Array
               
(
                   
[contractbegin] => Array
                       
(
                           
[month] => 11
                           
[day] => 17
                           
[year] => 2014
                       
)

                   
[contractperiod] => 12
                   
[Contractdetail] => Array
                       
(
                           
[memberfee] => 10.00
                       
)

                   
[Grant] => Array
                       
(
                           
[grantlevel] => 5.00
                           
[Grantedcourse] => Array
                               
(
                                   
[0] => Array
                                       
(
                                           
[coursename] => Spinning
                                       
)

                                   
[1] => Array
                                       
(
                                           
[coursename] => TaeBo
                                       
)

                               
)

                       
)

               
)

       
)

)




--
Like Us on FaceBook https://www.facebook.com/CakePHP
Find us on Twitter http://twitter.com/CakePHP

---
You received this message because you are subscribed to the Google Groups "CakePHP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cake-php+unsubscribe@googlegroups.com.
To post to this group, send email to cake-php@googlegroups.com.
Visit this group at http://groups.google.com/group/cake-php.
For more options, visit https://groups.google.com/d/optout.

No comments: