2010-11-29 6 views
4

J'ai un formulaire avec un champ de téléchargement de fichier et j'ai créé un fichier de comportement de modèle pour gérer le traitement de fichiers.Enregistrement du modèle dans afterSave() dans cakePHP

J'ai deux fonctions, BeforeSave et afterSave:

En beforeSave je fais des trucs et définir la valeur de fichier dans les données null afin qu'il puisse être sauvé. Sinon, il essaiera de sauvegarder un tableau, et la base de données attendra juste une chaîne (le nom du fichier)

Dans afterSave, je génère un nouveau nom de fichier basé sur certains champs de texte sur le formulaire, et j'ajoute lastInsertId en-dessous. Je déplace également le fichier de temp à l'emplacement désiré. Tout cela fonctionne très bien, mais quand j'essaie de sauvegarder le nouveau nom de fichier dans le modèle, ça ne marche pas.

J'ai fait beaucoup de test et de débogage, et j'ai passé des heures à chercher en ligne. La conclusion est que vous ne pouvez pas enregistrer dans afterSave, il se déclenche et s'exécutera avantSave à nouveau.

Donc, ma question est, comment puis-je mettre à jour le modèle nouvellement inséré? Le nom de fichier inséré doit avoir la clé primaire dans son nom et son inconnue au moment de beforeSave.

reconnaissant pour toute aide! jason

Répondre

6

Il peut se faire de cette façon

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

Petit Tweak (pas recommandé)

Si vous voulez contourner beforeSave sur les opérations db dans afterSave() utiliser $this->Model->query(), au lieu de $this->Model->save() ;

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

c'est où im le faire, mais son ne fonctionne pas. il semble initier beforeSave à nouveau, car c'est ce que je fais, ce qui sauve. – Jason

+0

@Jason, il va tirer avantSave si vous essayez de le sauvegarder à nouveau. au sein d'aftersave. essayez peu ajouté à la poste et laissez-moi savoir ce qui se passe – Ish

+0

comment voulez-vous dire? Comment puis-je sauvegarder avec query()? – Jason

0

Personnellement, tout le traitement de fichiers doit être effectué dans le contrôleur (ou le composant) après avoir enregistré votre modèle. Je ne pense pas qu'un modèle devrait gérer le dossier selon la conception de MVC.

Dans votre contrôleur

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

$model->save(); 

Hope this aide.

+0

merci, je vais le prendre en considération . mais pour le moment je préférerais continuer la route en allant, même si cela pourrait être contre le design de mvc. ce code est seulement pour mes yeux de toute façon :) – Jason

0

Idéalement, si votre nom est dépendant des autres colonnes dans la base de données, vous n'avez pas besoin de vos données resave modèle nouveau. En fait, cela introduirait des colonnes dans le schéma de votre table qui dépendent l'une de l'autre, ce qui va à l'encontre de la normalisation.

Par exemple. Si votre nom de fichier est de la forme "textfield1-textfield2-yourid.ext", vous devez stocker les valeurs de textfield1, textfield2 et ext dans la base de données. Ensuite, dans la méthode afterFind() de votre modèle, vous pouvez parcourir vos résultats en créant le nom de fichier généré en tant que nouveau champ dans votre tableau de données.

Tableau Exemple de schéma:

id | textfield1 | textfield2 | extension | created | modified 

Exemple Afficher le code:

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

Bien sûr, comme je l'ai mentionné plus tôt, cela peut être simplifiée si vous remplacez le afterFind() dans votre modèle et créez un nouveau champ appelé "filename". Plus sur cela sur here.

Cela raccourcirait votre code:

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

Et serait également plus facile de modifier universellement à tout moment.

+0

bonne idée, merci! – Jason

15

Si vous voulez contourner tous les callbacks (afterSave/BeforeSave) dans le afterSave() lui-même, je trouve cette syntaxe de travail pour moi:

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

Pour désactiver les déclencheurs, les états manuels en effet que:

La méthode de sauvegarde a également une autre syntaxe:

sauvegarde (tableau de données de $ = null, tableau $ params = array()) tableau $ params peut avoir l'une des options disponibles suivantes clés:

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

cela fonctionne parfaitement! – Vovkin

Questions connexes