2011-04-19 27 views
4

ここに私のbeforeSave関数があります。 checkExisting()は、$ this-> data内のいくつかのフィールドが一意であるかどうかをチェックし、存在するレコードがない場合はfalseを返します。存在する場合は既存のレコードのIDを返します。この関数は正常に動作しています。私は私のコードが何をすべきだと思う何CakePHP - モデル - > beforeSave()のinsertからupdateへの変更

public function beforeSave(){ 
    if ($this->checkExisting() !== false){ 
     $this->id = $this->checkExisting(); 
    } 
    return true; 
} 

はこれです:既存のレコードがある場合は、その既存のレコードのIDをモデル - > IDを設定し、その代わりに、インサートの更新するために、CakePHPのを強制します。

このコードが実際に行うことは、関係なく、新しいレコードを挿入することです。

$ this-> id = $ this-> checkExisting();を変更した場合、 $ this-> checkExisting(); $ this-> data ['Model'] ['id'] = $ this-> checkExisting(); MySQLは、Cakeがまだ更新するのではなく、挿入しようとしているのでエラー(主キーの重複値) 、データ。

Cakeはどの段階で更新ではなく挿入を行うことにしましたか? beforeSave()はこの決定に影響を与えるには遅すぎますか?

編集 - ここに私のコントローラコードがあります:

public function add(){ 
    if (!empty($this->data)){ 
     $saved = 0; 
     foreach($this->data['Attendance'] as $att){ 
      $this->Attendance->create(); 
      if ($this->Attendance->save(array('Attendance'=>$att))){ 
       $saved++; 
      } 
      if ($saved > 0){ 
       $this->Session->setFlash('Data saved successfully','success'); 
      }else{ 
       $this->Session->setFlash('No data was saved. Please make sure you have entered some data.','failure'); 
      } 
     } 
    } 
} 

それについて考え、私が明示的に出席を呼ぶという事実とは何かである::()を作成しますか?

答えて

2

いいえ、beforeSaveはこれを変更するには遅すぎることはありません。 Model-> save()は、次の順序で処理を行います。

  1. Model-> set()を呼び出して、指定されたデータを渡します。これは、IDを抽出し、モデル - を設定>
  2. コールが(beforeSave()を含む)の機能
  3. コールバック番号は、モデル - > idは上記コードは動作するはず

設定さに基づいて更新または挿入するかどうかを判断しcheckExisting()が正しく動作すると仮定します。 checkExisting()コードをもう一度見ていきます。

また、checkExisting()を2回呼び出してもコードが非効率的であることに注意してください。これは良いだろう:

$existing = $this->checkExisting(); 
if($existing) { 
    $this->id = $existing; 
} 

編集 レコードの1つが無効である場合、あなたのアドオン()アクションは上記の部分レコードセットを保存して終了するので、私は)あなたがcheckExistingを(作成したことを推測しています。 saveAll()を使用する必要があります。saveAll()は、すべてのレコードを保存する前に検証できます。

public function add() { 
    if(!empty($this->data)) { 
     if($this->Attendance->saveAll($this->data)) { 
      $this->Session->setFlash('Data saved successfully','success'); 
     } else { 
      $this->Session->setFlash('No data was saved. Please make sure you have entered some data.','failure'); 
     } 
    } 
} 
+0

おかげで、私は私のcheckExisting()関数をトリプルチェックしたのだが、それが虚偽またはレコードのIDを返す、必要として働いています。より多くのコード – Will

+0

のための私の編集は、上記の私の編集を参照してください見るCakePHPでは – Tyler

+2

は、UPDATEまたはINSERTであるかどうかを把握するために存在している()コールバックが早い順に、たまたま2.0.5。モデルにexists()を上書きします。 –

0

ユーザーがIDを必要とせずにフォームを送信できるようにする何かがありますか?通常、ユーザーがレコードを編集している場合は、すでにIDを持っていて、フォームが送信されたときにIDを確認する必要はありません。コントローラ内の関数は、IDを付けたレコードを送信し、モデルにSAVEではなくUPDATEであることを伝えます。

私のように、コードのどこかでショートカットを取っているかもしれません。保存/更新を行っているコントローラ機能を投稿しますか?その後、正しいヘルプを提供することができます。

+0

のようなファイルのmd5_file()は出回っデシベルであるかどうかを確認し、重複ファイルで終わるしないように、:一つの可能​​な解決策は、それが存在する場合は、レコードを削除することです。 –

2

コードまたはタイラーのコードが動作する場合は、何らかの奇跡でなければなりません。beforeSaveがCakeと呼ばれているときは、既にレコードセットが存在し、Updateが必要かどうかを知るためのクエリーを実行しました。 beforeSaveのUpdateに変更する方法はありません。 ADD_FILE上

public function beforeSave() { 
    $existing = $this->checkExisting(); 
    if($existing) { 
     $this->id = $existing; 
     $this->delete(); 
    } 
    return true; 
} 
関連する問題