Transações no CakePHP

31
mai
17h 36

Há várias maneiras de fazer transações no CakePHP. Aqui mostrarei uma delas que é o uso da função saveAll().

Vou exemplificar o seu uso com 2 modelos relacionados.

Imagine que estamos querendo construir um tipo de CRM. Nós teremos o modelo da Companhia, que guarda informações genéricas sobre a empresa. A Companhia tem muitas (hasMany) Contas, que irá guardar as informações relativas aos vários usuários que acessam o CRM.

Primeiro vamos criar as tabelas:

CREATE TABLE `companhias` (
 `id` int(11) NOT NULL auto_increment PRIMARY KEY,
 `nome` varchar(200) NOT NULL,
 `descricao` varchar(200) NOT NULL,
 `localizacao` varchar(200) NOT NULL,
 `created` datetime NOT NULL
);
CREATE TABLE `contas` (
`id` INT NOT NULL auto_increment PRIMARY KEY,
`companhia_id` int(11) NOT NULL,
`nome` VARCHAR( 200 ) NOT NULL,
`usuario` VARCHAR( 200 ) NOT NULL,
`email` VARCHAR( 200 ) NOT NULL,
`created` DATETIME NOT NULL
);

Depois vamos criar nossos modelos:

class Companhia extends AppModel {

 public $hasMany= array('Conta');

 public $validate = array(
 'nome' => array('rule' => array('notEmpty')),
 'descricao' => array('rule' => array('notEmpty'))
 );
}
class Conta extends AppModel {

 public $belongsTo = array('Companhia');

 public $validate = array(
 'nome' => array('rule' => 'notEmpty'),
 'usuario' => array('rule' => 'notEmpty'),
 'email' => array('rule' => 'email')

 );
}

Como se pode ver, os modelos são bem simples, apenas adicionamos algumas validações e o suficiente para os propósitos deste exemplo.

Agora vamos criar o controlador da Companhia, que por hora ficará em branco:

class CompanhiaController extends AppController {
    //
}

Agora que temos nossos modelos e um controlador, o próximo passo é criar algum formulário onde algum usuário do CRM irá cadastrar uma empresa e a primeira conta dela ao mesmo tempo. É aí que entra o saveAll(), porque ele nos permite salvar os dois modelos sem esforço.

Então vamos construir um formulário que nos permita criar a Companhia e a Conta (crie um arquivo chamado /companhias/add.ctp):

echo $form->create();
echo $form->input('Companhia.nome', array('label'=>'Nome da Empresa'));
echo $form->input('Companhia.descricao');
echo $form->input('Companhia.localizacao');
 
echo $form->input('Conta.0.nome', array('label'=>'Nome da Conta'));
echo $form->input('Conta.0.usuario');
echo $form->input('Conta.0.email');
 
echo $form->end('Add');

Vamos analisar o que temos aqui. Nós consideramos a Companhia para ser nosso modelo principal, portanto o formulário irá por padrão submeter para a ação de adicionar (add) do controlador da Companhialler (i.e. /companhias/add/).
Observe bem o modo como foi nomeado os campos do formulário do modelo Conta. Se a Companhia é nosso modelo principal, o saveAll() irá esperar que os dados de um modelo relacionado (Conta) cheguem num formato específico.
E tendo o Conta.0.nomeDoCampo é exatamente o que precisamos (isso só é verdadeiro para o relacionamento hasMany, para o hasOne os campos devem seguir o padrão Conta.nomeDoCampo).

Agora, no controlador Companhias nós podemos criar a ação add():

function add() {
   if(!empty($this->data)) {
      $this->Companhia->saveAll($this->data, array('validate'=>'first'));
   }
}

É fácil ou não é?

 

Baseado no artigo em inglês: http://nuts-and-bolts-of-cakephp.com/2008/08/01/practical-use-of-saveall-part-1-working-with-multiple-models/

Comentários encerrados.

 

O que está rolando na lista?