Dica: salvando vários registros de um mesmo model de uma só vez (dentro de um loop)

Olá pessoal,

esta dica é bem valiosa e foi mais um problema enfrentado durante a programação do meu projeto para a faculdade. No meu projeto o usuário pode enviar N imagens para o sistema de uma só vez. N imagens porque o campo file de envio é criado com JS de acordo com a necessidade e vontade do usuário.

A primeira coisa que pensamos é fazer o seguinte:

PHP:
  1. foreach($imagens as $imagem){
  2. $img["Imagem"]["nome"] = $imagem;
  3. $this->Imagem->save($img);
  4.  
  5. }

Legal, logicamente parece estar correto. Mas o que o Cake faz? Isso mesmo, ele cria um registro e os outros ele altera esse primeiro. Por quê? Porque a chave primária está preenchida.

A solução é bem simples, basta fazer isso:

PHP:
  1. foreach($imagens as $imagem){
  2. $img["Imagem"]["nome"] = $imagem;
  3.  
  4. $this->Imagem->id = null;
  5. $this->Imagem->save($img);
  6.  
  7. }

Setar o id da imagem (ou do model) como null. Este id após alguma inserção fica preenchido com o código autoincremento do último save. Sendo que o Cake dá um insert quando o mesmo é null e um update caso contrário.

Bom é isso...

Qualquer dúvida, comentem!

Abraços e até a próxima...

Comentários (17)

Dica: salvando automaticamente a data de criação e de última atualização quando a tabela não segue o padrão do CakePHP

Olá pessoal,

hoje passei por mais um problema no meu projeto por ele não usar a padronização do Cake no banco.

Como vocês devem saber o Cake popula automaticamente campos nomeados com CREATED, MODIFIED e UPDATED, sendo data de criação no primeiro e alteração nos dois últimos.

Pois bem, no meu projeto, que não segue o padrão do Cake tive que usar o callback do model, o beforeSave. O qual é executado antes do save do model e após a validação dos dados.
O código ficou assim dentro do meu model:

PHP:
  1. function beforeSave(){
  2. if (!isset($this->data["Model"]["CampoChavePrimária"])){
  3. $this->data["Model"]["CampoCriadoEm"] = date('Y-m-d H:i:s');
  4. }
  5. $this->data["Model"]["CampoModificadoEm"] = date('Y-m-d H:i:s');
  6. return true;
  7. }

Onde:

  • Model - seu model
  • CampoChavePrimaria - o campo chave primária da sua tabela que persiste o model
  • CampoCriadoEm - o campo que armazena a data de criação do registro
  • CampoModificadoEm - o campo que armazena a data de alteração do registro

Observe que o beforeSave retorna true, somente quando isso ocorre que é efetuado o save no banco.

Isso pode ser usado em outras situações, daí vai da criatividade, como criptografar a senha para guardar no banco e por aí vai...

Qualquer dúvida, comentem!

Até a próxima!

Comentários (8)

Dica: compartilhando models, controllers e views entre aplicações no CakePHP

Olá pessoal,

estou desenvolvendo meu projeto deste ano da faculdade em CakePHP e uma coisa que ainda não havia pensado em fazer era o compartilhamento dos arquivos MVC's.

No meu projeto, estou compartilhando os models entre as 4 aplicações que fazem parte do mesmo sistema. Então, como fazer?

A primeira coisa que fiz para acelerar as coisas foi mapear o banco, mas nisso já se foram aproximadamente 40 classes models :) , se eu copiasse e colasse nas outras partes do projeto, resultaria em 160 classes e com certeza em muita dor de cabeça para mantê-las sincronizadas.

A solução: bootstrap.php!

O arquivo bootstrap é carregado automaticamente depois que o arquivo app/webroot/index.php e depois que o bootstrap.php (nível núcleo do Cake) é carregado. É usado para adicionar qualquer função que não for usada numa classe, pode ser usado também para dar um include/require em qualquer arquivo da sua aplicação.
No meu caso que queria adicionar um diretório para os models, então usei, nas minhas demais aplicações (tal como app2, app3 e etc):

PHP:
  1. $modelPaths = array(ROOT.DS."app".DS."models".DS);

Assim, sempre será buscado (também) os models em: /app/models/. Lembrando que DS é o directory separator, que no windows é \ e no linux é / e ROOT representa o caminho físico da instalação do Cake.

Para usar com views e controllers é a mesma configuração, mas usando:

PHP:
  1. $controllerPaths = array(ROOT.DS."app".DS."controllers".DS);
  2.  
  3. $viewPaths = array(ROOT.DS."app".DS."views".DS);

Qualquer dúvida, comentem!

Até a  próxima pessoal!

Comentários (10)