user3790914
user3790914

Reputation: 43

Save data in two tables in CakePHP

I have a simple form in Cake :

enter image description here

I want to save the informations in the users and companies tables .

Users Table :

enter image description here

Companies table :

enter image description here

I'm in need to get two sql queries .

First of all : - Insert the new users with a new company id which will be created in companies table .

For instance with this case, testza,

users : (new entry) testza password company id (new if of the new company entry)

companies (new entry) : Id (3) Creaz (name) 500 000 (revenue_generated) .

I guess i'm clear :

companies/signup (view)

<div class="page-header">

    <h1>Company Registration</h1>

</div>

<?php echo $this->Form->create('Company'); ?>

        <?php echo $this->Form->input('User.username',array('label'=>'Login')); ?>

        <?php echo $this->Form->input('User.password',array('label'=>'Password')); ?>

        <?php echo $this->Form->input('User.passwordconfirm',array('label'=>'Confirm password','type'=>'password')); ?>

        <hr>

        <?php echo $this->Form->input('Company.company_id', 
        array(
            'label'=>'Company',
            'options' => $companies,
            'empty' => 'Select Company Name'
        ));
        ?>

        <?php echo $this->Form->input('Company.revenue_generated',array('label'=>'Revenue Generated')); ?>

<?php echo $this->Form->end('Envoyer'); ?>

the action signup of the Controller CompaniesController

<?php

class CompaniesController extends AppController{

    public $uses = array('User');

    public function signup() {

        $this->loadModel('Company');

        $companies = $this->Company->find('list'); //we get the authors from the database

        $this->set('companies', $companies);

        if($this->request->is('post') || $this->request->is('put') ){

            $d = $this->request->data['User'];
            $c = $this->request->data['Company'];

            if($d['password'] != $d['passwordconfirm']){

                $this->Session->setFlash("Les mots de passes ne correspondent pas","notif",array('type'=>'error'));

            }

            else{

                if(empty($d['password']))

                    unset($d['password']);

                if($this->User->save($d) || $this->Company->save($c)){

                    $this->Session->setFlash("L'utilisateur a bien été enregistré","notif");

                }

            }

        }
    }
..............

User Model :

<?php 

class User extends AppModel{

    public $actsAs = array('Containable'); 

     public $belongsTo = array(        
        'Town' => array(
            'className' => 'Town'
        ),
        'Company' => array(
            'className' => 'Company'
        )
    ); 

    public $recursive = -1; 

    public $order = 'User.id DESC';

    public $validate = array(

        'username' => array(

            'rule'       => 'isUnique',

            'allowEmpty' => false,

            'message'    => "Ce nom d'utilisateur est déja pris"

        ),

        'password' => array(

            'rule'       => 'notEmpty',

            'message'    => "Vous ne pouvez pas entrer de mot de pase"

        )

    );

    public function beforeSave($options = array()){

        if(!empty($this->data['User']['password'])){

            $this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);

        }

        return true; 

    }

}

Company Model :

<?php 

class Company extends AppModel{

    public $validate = array(
        'revenue_generated' => array(
            'rule' =>'notEmpty',
            'message' => 'Enter Your Generated Revenue.',
            'required' => true
        )
    );

}

Upvotes: 0

Views: 4303

Answers (2)

Since you are going to use an existing company already in the database from the drop down menu, try saving both models at the same time with Model::saveAssociated(). This will save both records at once for you, and insert the Company id, automatically into the foreign key for the users table: User.company_id on successful save.

Replace your two save() function calls with one call to saveAssociated():

if($this->User->saveAssociated($data)) {
    //do something after save.
}

Here is a complete example using your existing code:

$this->set('companies', $this->Company->find('list'));

if($this->request->is(array('post', 'put'))) {

    //Dont need to seperate this anymore
    //$d = $this->request->data['User'];
    //$c = $this->request->data['Company'];

    if($this->request->data['User']['password'] != $this->request->data['User']['passwordconfirm']){
        $this->Session->setFlash("Les mots de passes ne correspondent pas","notif",array('type'=>'error'));
    } else {

        if(empty($this->request->data['User']['password']))
            unset($this->request->data['User']['password']);

        if($this->User->saveAssociated($this->request->data)){
            $this->Session->setFlash("L'utilisateur a bien été enregistré","notif");
        }
    }
}

The Company model is also missing the hasMany relationship for User. Add this to Company model:

public $hasMany = array('User');

Refer to Cake Manual here for documentation on SaveAssociated(): http://book.cakephp.org/2.0/en/models/saving-your-data.html#model-saveassociated-array-data-null-array-options-array

Upvotes: 2

may saghira
may saghira

Reputation: 564

here is the solution i suggest and i work with, start by saving the company first to generat the id the save the user :

if($this->Company->save($this->request->data['Company'])){
$this->Company->User->save($this->request->data['User']); // if save doesn't work try $this->Company->User->saveAll($this->request->data['User']);
...
}

update : add the hasmany relation in the company model :

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

hope ut helps.

Upvotes: 1

Related Questions