2010-11-29 27 views
4

私はファイルアップロードフィールドを持つフォームを持っています。ファイル処理を処理するモデル動作ファイルを作成しました。 beforeSaveでcakePHPのafterSave()でモデルを保存する

私はいくつかのものを行うと、それを保存することができますので、nullにデータ内のファイル値を設定します。

は、私は2つの機能、beforeSaveとafterSaveを持っています。それ以外の場合、配列を保存しようとします。データベースはただの文字列(ファイル名)を返します。

afterSaveでは、フォームのテキストフィールドに基づいて新しいファイル名を生成し、その最後のlastInsertIdを追加します。私はまたファイルをtempから目的の場所に移動します。 これはうまくいきますが、新しいファイル名をモデルに保存しようとすると、それは機能しません。

私は多くのテストとデバッグを行いましたし、オンラインでの検索にも時間を費やしました。結論は、あなたがafterSaveで保存することができないということです、それはそれ自身を引き起こし、前に実行して保存します。

私の質問は、新しく挿入したモデルをどのように更新できますか?挿入されたファイル名はその名前にプライマリキーが必要であり、beforeSaveの時刻には未知のものです。

ご協力いただきありがとうございます。 jason

答えて

6

あなたは(afterSaveにDB操作にbeforeSaveをバイパスしたい場合は、代わりに$this->Model->save()の、$this->Model->query()を使用)このよう

// Its your model Image.php 
function afterSave($created) { 
    if($created) { 
     // its new record 
     // do your work here 
    } 
} 

リトル微調整を推奨しません)

行うことができます;

// little hack to bypass beforeSave 
$this->Model->query('UPDATE listings SET name="xx" WHERE id="1"'); 
+0

それは私がそれをやっているが、その動作していないthats。それは前に始まっているように見えます。 – Jason

+0

@jason、もう一度保存しようとすると保存前に保存されます。後で保存します。投稿するには少し追加してみて、何が起こったのか教えてください。 – Ish

+0

どういう意味ですか? query()でどのように保存できますか? – Jason

0

個人的には、モデルを保存した後、すべてのファイル処理はコントローラ(またはコンポーネント)で行う必要があります。私はMVCの設計に従ってモデルがファイルを管理すべきだとは思わない。お使いのコントローラで

// Save model 
if ($model->save()) { 
    // Save your file 
    ... 
    // Update the model 
    $model->updateField(); 
} 

$model->save(); 

は、このヘルプを願っています。

+0

はあなたに感謝し、私は考慮にそれを取るでしょう。しかし、現時点では、たとえそれがmvcデザインに反するかもしれないとしても、私は行くルートを行くことを好むだろう。このコードはとにかく私の目のためだけです:) – Jason

0

あなたのファイル名は、データベース内の他の列に依存している場合には理想的には、あなたは再びあなたのモデルデータを再保存する必要はありません。実際には、テーブルのスキーマ内に互いに依存する列が導入されるため、正規化には反対します。

例:ファイル名の形式が "textfield1-textfield2-yourid.ext"の場合、textfield1,textfield2およびextという値をデータベースに保存する必要があります。モデルのafterFind()メソッドでは、結果をループして、生成されたファイル名をデータ配列の新しいフィールドとして作成できます。

サンプルテーブルスキーマ:

id | textfield1 | textfield2 | extension | created | modified 

サンプルビューコード:もちろん

echo $this->Html->image("{$data['Picture']['textfield1']}-{$data['Picture']['textfield2']}-{$data['Picture']['id']}.{$data['Picture']['extension']}"); 

、私は先に述べたように、あなたがafterFindを上書きした場合、これは(単純化することができる)でモデルを作成し、「ファイル名」という新しいフィールドを作成します。詳しくはhere以上。

これはにあなたのコードを短縮します:

echo $this->Html->image($data['Picture']['filename']); 

そしてまた、それが簡単に任意の時点で普遍的に修正することになるだろう。

+0

良いアイデア、ありがとう! – Jason

15

あなたはバイパスにafterSave()自体にすべてのコールバックを(afterSave/beforeSave)したい場合は、私はこの構文は私のために働いた:

$this->save($data, array('callbacks'=>false)); 

トリガ、マニュアルの状態を無効にするには確かにその:

保存方法は、また別の構文を持っています

(配列$データ= nullを、配列$ paramsは=配列()) $ params配列は次の有効なオプションをキーとして持つことができます割引:

array(
    'validate' => true, 
    'fieldList' => array(), 
    'callbacks' => true //other possible values are false, 'before', 'after') 
+0

それは完全に動作します! – Vovkin

関連する問題