Dica: validando mais de um model em uma mesma requisição antes de salvar

Provavelmente, você já deve ter pensando em fazer um cadastro de alguma informação, onde, de uma vez só cadastrasse informações sobre dois Models.

Uma maneira rápida seria:

PHP:
  1. if($this->Model1->save($this->data)&&$this->Model2->save($this->data)) {
  2. $this->flash('Dados salvos.', '/');
  3. }

Esta solução até que funciona bem. Caso não tenhamos relação entre os Models. Ou seja, seria bem improvável que os mesmos seriam salvos em um mesmo lugar sem ter nenhuma relação. Se percebemos bem ainda teremos outro problema, caso desejamos validar os dados dos dois Models antes de salvar qualquer um deles. Já que nesse caso, se o Model1 for salvo, já é inserido os dados no banco, mesmo que o save do Model2 falhe.

Uma alternativa interessante seria:

PHP:
  1. $v1 = $this->Model1->validates($this->data);
  2.  
  3. $v2$this->Model2->validates($this->data);
  4.  
  5. if($v1&&$v2) {
  6.  
  7. $this->Model1->save($this->data);
  8.  
  9. $this->data["Model2"]["model1_id"] = $this->Model1->getLastInsertId();
  10.  
  11. $this->Model2->save($this->data);
  12.  
  13. $this->flash('Dados salvos.', '/');
  14. }

Assim, primeiro validamos os dois models, e somente se passar pelas duas validações, inserimos os dados no banco. Mantendo assim a consistência dos dados. Poderíamos também já pegar a chave estrangeira e colocar no outro model, com getLastInsertId.

Podemos usar tranqüilamente o tagErrorMsg no view, que ele irá funcionar, pois o validates se encarregará disso.

Abraços pessoal e até a próxima. Dúvidas? Comentem!

4 Comentários »

  1. Henrique said,

    Maio 1, 2007 @ 01:20

    Muito bom!

    Já pensou em escalar isso num método pra N models? Daria até pra incluir no próprio Cake.

    Ótimo blog. Abraço!

  2. Tulio Faria said,

    Maio 3, 2007 @ 18:29

    Olá Henrique,

    poderia até ser em um behavior e colocado no app_model para ser executado de modo automático... Aliás, vou pensar nisso...

    Obrigado pelo elogio, t+

  3. Danilo Miguel said,

    Junho 13, 2007 @ 10:45

    Cara, eu achei uma outra forma de fazer isso (baseado inclusive em algumas coisas que peguei no site que vc disponibilizou para exemplo):

    $campos = array('url','name','email','phone','address','number','town','city','cep','uf');
    $models = array('Site','Client','User');
    $v = true;
    foreach($campos as $campo){
    foreach($models as $model) {
    if(empty($this->data['Site'][$campo]) && empty($this->data['Client'][$campo]) && empty($this->data['User'][$campo])) {
    //if(empty($this->data[$model][$campo])) {
    $this->$model->invalidate($campo);
    $v = false;
    }
    }
    }

  4. Leandro de Sousa said,

    Fevereiro 19, 2009 @ 17:55

    E ai Túlio, blz?

    To precisando fazer uma coisa mais ou menos assim:

    - Tenho uma tabela entrada (vou digitar qtas peças comprei por exemplo) e tenho a tabela de estoque que está relacionada com a entrada, então quando digitar a qtde de peças na entrada, eu vou indicar qual peça e qtas está entrando, eu queria atualizar nessa hora automaticamente a tabela de estoque pegando o qtde_entrada que foi digitado e somar a qtde_estoque (tabela estoque).
    - Minha tabela entrada:
    id
    peca_id
    qtde_entrada
    precoCompra_entrada
    precoVenda_entrada
    created

    - Minha tabela estoque:
    id
    entrada_id
    saida_id
    qtde_estoque
    data_atualizacao
    created

    Tentei fazer algo parecido com esse modelo seu ai e não fui feliz :(, se puder me dar uma luz, fico grato :)

    Inté +
    Obrigado

RSS feed for comments on this post · URI do TrackBack

Deixe seu comentário