2011-01-24 25 views
3

私は5つのフィールドを持つ比較的単純なエントリーモデルがあります:saveAllの使用時にCakephpのbeforeSaveに新しいデータが残っていませんか?

  1. ID(このエントリが何であるか、データ型)
  2. タイプ
  3. 量を(どのようにそれが何であれタイプの多く)(
  4. ユニットタイプのユニット)
  5. 日付(このエントリが入力されたdatettime)
  6. USER_ID(
に入るユーザのID

それでは、何も気にしません。単一のフォームは複数のエントリを持つことができます(既に存在するものと新しいものの両方を作成できます)。フォームはajax呼び出しによって拡張されます。私は、フォームを送信すると

$this->dataは以下のようになります。

Array 
(
    [Entry] => Array 
     (
      [date] => 2011-01-07 
      [0] => Array 
       (
        [id] => 1 
        [type] => Eat 
        [amount] => 1 Steak, one baked potatoe 
        [unit] => lunch 
        [time] => Array 
         (
          [hour] => 13 
          [min] => 31 
         ) 

       ) 

      [1] => Array 
       (
        [type] => weight 
        [amount] => 78.5 
        [unit] => KG 
        [time] => Array 
         (
          [hour] => 22 
          [min] => 22 
         ) 

       ) 

     ) 

) 

$this->data['Entry']['date']の最初のエントリは、すべてのエントリで使用しなければならない日です。そしてuser_idも見つからないので、私はエントリーモデルで "beforeSave"関数を作成しました。それは次のようになります。

function beforeSave() { 
    App::import('Component','Session'); 
    $this->Session = new SessionComponent(); 

    if (isset($this->data) && isset($this->data['Entry'])) { 
     $date = $this->data['Entry']['date']; 
     unset($this->data['Entry']['date']); 

     foreach ($this->data['Entry'] as $n => $entry) { 
      if (is_array($entry)) { 
      $this->data['Entry'][$n]['date'] = $date . ' ' . $entry['time']['hour'] . ':' . $entry['time']['min'] . ':00'; 
       $this->data['Entry'][$n]['user_id'] = $this->Session->read('Auth.User.id'); 
      } 
     } 
     debug($this->data); 

    } 
    return true; 
} 

私は、日付を削除するためのMySQLのdatetimeエントリを作成し、ユーザーのタイムエントリと一緒にそれを追加して、ログインしているユーザーのUSER_IDを追加します。まっすぐ、本当に。 (その最後のdebug()によって出力など)結果の配列は、以下のようになります。

Array 
(
    [Entry] => Array 
    (
     [0] => Array 
      (
       [id] => 1 
       [type] => Eat 
       [amount] => 1 Steak, 1 baked potatoe 
       [unit] => lunch 
       [time] => Array 
        (
         [hour] => 09 
         [min] => 31 
        ) 

       [date] => 2011-01-07 09:31:00 
       [user_id] => 2 
      ) 

     [1] => Array 
      (
       [type] => Weight 
       [amount] => 78.5 
       [unit] => KG 
       [time] => Array 
        (
         [hour] => 22 
         [min] => 22 
        ) 

       [date] => 2011-01-07 22:22:00 
       [user_id] => 2 
      ) 

    ) 

) 

は、だから、私はそれを見てみたいとまったく同じように見て、それが簡単に保存する必要があります。しかし、私は $this->Entry->saveAll($this->data['Entry']を使用してすべてのエントリを保存するだけでなく、機能しないだけでなく、saveAllの直後に $this->dataをデバッグすると、saveAll関数の前に正確に似ています - 日付は配列に戻ります。 dateまたはuser_idエントリがあります。

私はbeforeSaveが呼び出されることがわかります、私はそれが$this->dataを変えることがわかりますが、どこかbeforeSaveの終わりと「SAVEALL」の用法の間に私のすべての変更が失われた取得し、$this->dataは、それが元の状態だと戻っています。したがって節約は行われません。

答えて

6

私はhasManyを使っていくつかのサニタイズを実装しようとしているのと同様の問題がありました。問題は、saveAll()がどのように動作するかにあります。コントローラの$ this->データはModel :: beforeSave()コールバックの$ this-> dataと同じではなく、2つは同期していません。 Model :: saveAll()を呼び出してコントローラから$ this-> dataを渡すと、データ配列のモデル "旧バージョン"が明示的に与えられます。そして、あなたはケーキ/ libsに/モデルにSAVEALL定義に見たときに/それをmodel.phpだけで行います。

if (empty($data)) { 
    $data = $this->data 
} 

とモデルに修正$ data配列を同期するには、何よりも、パラメータ$データから渡されたコントローラを構成します。解決策はsaveAll()にデータを渡すのではなく、Model :: set()を使用してモデルのデータを最初に設定し、Model :: saveAll()を呼び出します($ dataパラメータなし)。

+0

これは少なくとも動作を使用すると動作しません。:_( – elboletaire

0

限り、私はSAVEALL()すべて更新()とDELETEALLは()あなたは(メソッドの最後のパラメータ)

+0

いいえ、beforeSave関数内のデバッグが問題なく新しいデータ構造を表示していたため、コールバックがうまく起動しました。 – Sorcy

0

あなたがいないなら、手動でそれらを有効にする必要があり、デフォルト

ことにより、任意のコールバックをトリガいけない知っているようにバリデーションであなたがうまくいくのはあなたですか?

は、主キーが指定されていない場合は、単一のモデルのために保存する前に)それが動作する場合、問題は、しかし、あなたは(作成に使用する必要があることを忘れないでください、検証

にある

$this->Entry->saveAll($data,array('validate'=>false)); 

を試してみてください。 saveAll()の新しいデータと既存のデータを混在させることが問題なのかもしれません。

+0

このモデルの検証はありませんでした。また、私はbeforeSave関数をコントローラに移したので、正常に動作します。私は機能の中で何も変更しませんでしたが、コントローラ内で呼び出されると、beforeSaveで呼び出されたときにデータ構造が保持されますが、そうではありません。 – Sorcy

1

SaveAllを呼び出すと、更新/送信されたデータがモデルのbeforeSaveに渡されません。

がモデルでtmp_data配列を作成し、この問題から出てくるように

つまり、この変数を設定SAVEALL呼び出し、前

var $tmp_data = array(); 

、 すなわち

$this->model->tmp_data = $this->data; 
$this->model->saveAll(); 

はその後、ためのコードを修正model-> beforeSaveBefore の代わりに$this->data use $this->tmp_data

関連する問題