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!

3 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;
    }
    }
    }

RSS feed for comments on this post · URI do TrackBack

Deixe seu comentário