2009-07-01 21 views
2

J'ai un modèle CakePHP - Utilisateur - qui a des liens avec un système d'entreprise externe. Je stocke certaines données sur ces systèmes et d'autres données localement. Dans ma méthode User::beforeSave(), j'essaie de définir un ID, d'envoyer les données (avec cet ID personnalisé) à mes systèmes d'entreprise puis, s'il y est inséré, de renvoyer true afin que Cake insère le nouvel enregistrement utilisateur avec le même ID pour que je puisse les lier plus tard.CakePHP: Est-il possible d'insérer un enregistrement avec une valeur de clé primaire prédéfinie?

Je n'arrive pas à trouver un moyen d'y arriver. Y a-t-il un moyen pour d'insérer un enregistrement CakePHP avec une valeur de clé primaire spécifiée par l'utilisateur? J'utilise des UUID pour qu'il n'y ait (effectivement) aucune possibilité de chevauchement.

$this->data['User']['id'] = String::uuid() 

try { 
    $user_proxy = new CoreServicesUserProxy(); 

    $corp_user = $user_proxy->CreateUser (

     array (

     'user' => array (

      'UserName'  => 'myusername', 

      'EmailAddress' => $this->data['User']['email'], 

      'SecurityId' => $this->data['User']['id'] 

     ) 

    ) 

    ); 
} 
catch (Exception $e) { 
    // error handling stuff 
    return false; 
}
+0

Avez-vous essayé de définir $ Model-> id avec data ['User'] ['id']? Serait-il correct si vous insérez simplement un nouvel utilisateur dans une transaction, obtenez le nouvel identifiant, appelez le service et si tout s'est bien passé, validez simplement? –

+0

Non, je suppose que je n'ai pas fait ça. Je pensais que cela forcerait une mise à jour plutôt que d'insérer si je lisais les docs correctement. Pour l'instant, j'ai déplacé l'appel de l'API vers User :: afterSave() et ça marche bien, ce n'est pas ma séquence idéale. Je vais regarder dans les transactions, mais je me demande si je peux utiliser ceux-ci tout en engageant un rappel. Merci pour votre aide. –

Répondre

1

Je me rends compte que vous avez déjà reçu quelques indices, mais voici un code qui pourrait vous aider. Pourquoi ne pas ajouter un champ external_user_id à votre tableau users?

<?php 
class User extends AppModel { 

    function beforeSave() { 
     $ds = ConnectionManager::getDataSource('core_services'); 
     $externalUser = $ds->createUser($this->data); 
     if (!$externalUser) { 
      return false; 
     } 
     $this->data['User']['external_id'] = $externalUser['id']; 
     return true; 
    } 

    function afterFind($results, $primary) { 
     // handle different types of find here ('all' vs 'first' vs through relation) 
     foreach ($results as &$result) { 
      $result = $this->_mergeExternalUser($result); 
     } 
    } 

    function _mergeExternalUser($user) { 
     $ds = ConnectionManager::getDataSource('core_services'); 
     $externalUser = $ds->retrieveUser($result['external_id']); 
     return am($externalUser, $user); 
    } 

} 
?> 
+0

Honnêtement, la seule raison est l'économie de l'effort. Mon premier choix est de le faire d'une manière aussi laconique que possible (pas d'effort supplémentaire, d'entités, etc.). Si ce n'est pas possible - et il semble que ce ne soit pas le cas - alors je vais m'adapter de la manière la plus simple possible. Dans ce cas, en déplaçant l'appel de l'API vers le callback afterSave(), j'évite d'avoir à gérer des données supplémentaires. Pas mon monde parfait, mais ça suffira. :-) Merci. –

+0

Cette question a traîné assez longtemps que je pense qu'il est juste de supposer que ce n'est tout simplement pas possible (dans 1.2.x au moins). Je vais marquer cela comme la réponse, car c'est une solution de contournement solide. Ce que j'ai réellement fait était inverser l'ordre d'appel - sauvegarde locale d'abord, sauvegarde à distance en second lieu. Si l'enregistrement à distance échoue, je annule l'enregistrement local. –

1

Il est un moyen - mais en général, vous ajouterait une autre colonne à la table des utilisateurs à la place et laisser CakePHP faire est chose avec la clé primaire. Voir ce Bakery article pour savoir comment c'est fait. Puisque c'est plus d'un an plus tard, c'est pour référence surtout. Pour autant que je sache, cela devrait aussi bien fonctionner avec CakePHP 1.2.

Questions connexes