3
votes

I have a very strange problem using CakePHP 2.2.4, let me explain what happen.

I have these mysql tables:

leads

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_id    | int(11)      | YES  | MUL | NULL    |                |
| date       | datetime     | YES  |     | NULL    |                |
| ip         | varchar(45)  | YES  |     | NULL    |                |
| service_id | int(11)      | YES  | MUL | NULL    |                |
| location   | varchar(255) | YES  |     | NULL    |                |
| message    | text         | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

users

+---------+--------------+------+-----+---------+----------------+
| Field   | Type         | Null | Key | Default | Extra          |
+---------+--------------+------+-----+---------+----------------+
| id      | int(11)      | NO   | PRI | NULL    | auto_increment |
| email   | varchar(200) | YES  |     | NULL    |                |
| pwd     | varchar(200) | YES  |     | NULL    |                |
| role_id | int(11)      | YES  | MUL | NULL    |                |
| active  | tinyint(4)   | YES  |     | 0       |                |
+---------+--------------+------+-----+---------+----------------+

profiles

+---------+--------------+------+-----+---------+----------------+
| Field   | Type         | Null | Key | Default | Extra          |
+---------+--------------+------+-----+---------+----------------+
| id      | int(11)      | NO   | PRI | NULL    | auto_increment |
| user_id | int(11)      | YES  | MUL | NULL    |                |
| name    | varchar(120) | YES  |     | NULL    |                |
| surname | varchar(120) | YES  |     | NULL    |                |
| company | varchar(200) | YES  |     | NULL    |                |
| vat     | varchar(60)  | YES  |     | NULL    |                |
+---------+--------------+------+-----+---------+----------------+

addresses

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| profile_id | int(11)      | YES  | MUL | NULL    |                |
| address    | varchar(255) | YES  |     | NULL    |                |
| city       | varchar(120) | YES  |     | NULL    |                |
| zip_code   | char(5)      | YES  |     | NULL    |                |
| nation     | varchar(120) | YES  |     | NULL    |                |
| telephone  | varchar(200) | YES  |     | NULL    |                |
| mobile     | varchar(200) | YES  |     | NULL    |                |
| fax        | varchar(200) | YES  |     | NULL    |                |
| email      | varchar(200) | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

roles

+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(100) | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+

services

+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(255) | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+

and the follow are all the CakePhp Models I use (with the associations):

Lead.php

class Lead extends AppModel {

    public $name = 'Lead';

    /* Relazioni */      
    public $belongsTo = array('User', 'Service');
}

User.php

class User extends AppModel {

    public $name = 'User';

    /* Relazioni */
    public $hasOne = 'Profile';

    public $belongsTo = 'Role';

    public $hasMany = array(
        'Lead' => array(
            'className' => 'Lead'
        )
    );  

}

Profile.php

class Profile extends AppModel {

    public $name = 'Profile';

    /* Relazioni */
    public $belongsTo = 'User';

    public $hasMany = array(
        'Address' => array(
            'className' => 'Address'
        )
    );  

}

Address.php

class Address extends AppModel {

    public $name = 'Address';

    /* Relazioni */        
    public $belongsTo = 'Profile';

}

Service.php

class Service extends AppModel {

    public $name = 'Service';

}

I have a form that must to be saves in more than one mysql table.

This is the code i use to draft the FORM:

<?php

echo $this->Form->create(null, array(
                            'inputDefaults' => array(
                                'error' => false
                            )
                        )
                ); //create(false) per il form senza il modello

echo $this->Form->input('User.Profile.name', array(
                            'label' => array(   
                                'class' => 'name-form',                                                                                                                                         
                                'text'  => 'Nome:'                                                                      
                            ),                                                              
                            'style' => 'width:238px;',
                            'div'   => 'field'
                        )
               );                               

echo $this->Form->input('User.Profile.surname', array(
                            'label' => array(   
                                'class' => 'name-form',                                                                                                                                         
                                'text'  => 'Cognome:'                                                                       
                            ),                                                              
                            'style' => 'width:238px;',
                            'div'   => 'field'
                        )
               );                                   

?>

<div class="clear"></div>

<?php

echo $this->Form->input('User.email', array(
                            'label' => array(                                                                       
                                'class' => 'name-form',
                                'text'  => 'Email:'
                            ),                                                              
                            'div'   => 'field', 
                            'class' => 'input-xlarge'
                        )
               );

echo $this->Form->input('User.Profile.Address.telephone', array(
                            'label' => array(   
                                'class' => 'name-form',                                                                                                                                         
                                'text'  => 'Telefono:'                                                                      
                            ),                                                          
                            'div'   => 'field'
                        )
               );                          
?>

<div class="clear"></div>


<?php                      

echo $this->Form->input('Lead.service_id',
                    array(
                        'label' => array(                                                                       
                            'class' => 'name-form',
                            'text'  => 'Servizio richiesto:'
                        ),                                                              
                        'div'   => 'field',
                        'type'  => 'select',                                                                
                        'options' => $services                                      
                    )
);                              

echo $this->Form->input('Lead.location', array(
                            'label' => array(                                                                       
                                'class' => 'name-form',
                                'text'  => 'Vicino a:'
                            ),                                                              
                            'div'   => 'field', 
                            'class' => 'input-xlarge'
                        )
               );                               

?>

<div class="clear"></div>


<?php

echo $this->Form->input('Lead.message', array(
                            'label' => array(                                                                       
                                'class' => 'message-form',
                                'text'  => 'Richiesta:'
                            ),                                                              
                            'div'   => 'field', 
                            'class' => 'form-field',
                            'type'  => 'textarea'
                        )
               );                                                               

echo $this->Form->button('Invia Richiesta', array(
                                        'type'  => 'submit',
                                        'class' => 'submit-btn less-margin'
                                    )
                );

echo $this->Form->end();

?>

And this is the action of the controller(PagesController) that saves the data:

public function home() 
{       
   if ($this->request->is('post'))
   {
    $this->loadModel('Lead');

    $this->request->data['Lead']['ip']   = $_SERVER['REMOTE_ADDR'];
    $this->request->data['Lead']['date'] = date('Y-m-d H:i:s'); 
    $this->request->data['User']['role_id'] = 3;    

    $this->Lead->set($this->request->data);

    debug($this->request->data);

    if ($this->Lead->validates()) 
    {
        // Dati nel modulo corretti
        debug($this->Lead->saveAll($this->request->data, array('deep' => true)));
    } 
    else 
    {
        // Errore nella validazione
        $this->Session->setFlash('Completare correttamente il form', 'default', array('class' => 'errore'), 'lead');

        $errors = $this->Lead->validationErrors;                
        debug($errors);
    }   
}

$this->loadModel('Service');

$this->set('services', $this->Service->find('list'));               

}

And this is the output generated from the FORM:

array(
    'User' => array(
        'Profile' => array(
            'name' => 'The Name',
            'surname' => 'The Surname',
            'Address' => array(
                'telephone' => 'The Telephone'
            )
        ),
        'email' => '[email protected]',
        'role_id' => (int) 3
    ),
    'Lead' => array(
        'service_id' => '1',
        'location' => 'The location',
        'message' => 'This is the request',
        'ip' => '127.0.0.1',
        'date' => '2013-01-01 08:07:42'
    )
)

PROBLEM:

All work correctly, except one thing... saveAll() saves all the data correctly (in each model), but in the addresses table I only see that CakePhp insert profile_id, only this field, but as you can see in the array generated from the FORM, I also have the telephone!

Why does cakephp not also insert the telephone field?

Thank you

2
You need to view book.cakephp.org/2.0/en/models/…. Specifically the part that says: it is important to realize that saving model data should always be done by the corresponding CakePHP model - Tim Joyce
@TimJoyce pardon, i do not getting you... are you telling to me that if I have 3 groups of fields (for group I mean...field related to different models), do I have to do Model1->save() ... Model2->save() --- Model3->save() again and again ? do you mean it ? - Dail
Yes, this example here: book.cakephp.org/2.0/en/models/… should set you on the right path to saving related model data. - Tim Joyce
@TimJoyce before I have followed this method, but if i have to use ->save() for each Model, when do I need to use saveAll() ? - Dail
@TimJoyce and again...is this not too redundant? because at the moment all works good, except (telephone) but cakephp write in addresses table because i see the correct profile_id - Dail

2 Answers

2
votes

You are making up code, hence it does not work.

Nowhere in the cake docs does it say to use the following code:

Incorrect

$this->Form->input('User.Profile.surname');
$this->Form->input('User.Profile.Address.telephone');

You can not just string words together and hope for the best. You can either use:

Correct

$this->Form->input('field');
$this->Form->input('Model.field');
$this->Form->input('Model.n.field');

There are no other valid ways to enter fields.

Instead of making things up, read the docs

$this->Form->input('Profile.surname');
0
votes

"The saveAll function is just a wrapper around the saveMany and saveAssociated methods."

Try using saveAssociated instead so that you are forcing the saveAssociated method. Still pass the array('deep'=>true);. The way your output is formatted, it may be trying to automatically use saveMany.

Also, if you have validation on your telephone field in your model, it will fail since you have a string in there that does not contain any numbers. The Telephone. Or, you can pass the option of 'validate' => false.