【问题标题】:CakePHP: Is it possible to insert record with pre-defined primary key value?CakePHP:是否可以插入具有预定义主键值的记录?
【发布时间】:2009-07-01 18:55:09
【问题描述】:

我有一个与外部公司系统相关联的 CakePHP 模型 - 用户。我将一些数据存储在这些系统上,并在本地存储其他数据。在我的User::beforeSave() 方法中,我正在尝试设置一个 ID,将数据(使用该自定义 ID)发送到我的公司系统,然后,如果它成功插入到那里,则返回 true,以便 Cake 将插入新的用户记录相同的 ID,以便我以后可以链接它们。

我找不到实现这一点的方法。有没有办法插入具有用户指定主键值的 CakePHP 记录?我正在使用 UUID,因此(实际上)没有重叠的机会。

$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;
}

【问题讨论】:

  • 您是否尝试将 $Model->id 与 data['User']['id'] 一起设置?如果您只是在事务中插入一个新用户,获取新 id,调用服务,如果一切顺利,只需提交就可以了吗?
  • 不,我想我没有那样做。我认为如果我正确阅读文档,这将强制更新而不是插入。目前,我已将 API 调用移至 User::afterSave() 并且它工作正常,但这不是我理想的顺序。我会调查交易,但我想知道是否可以在使用回调的同时使用这些交易。感谢您的帮助。

标签: cakephp


【解决方案1】:

我知道您已经得到了一些提示,但这里有一些代码可能会有所帮助。

为什么不在users 表中添加external_user_id 字段?

<?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);
    }

}
?>

【讨论】:

  • 老实说,唯一的原因是省力。我的第一选择是以尽可能简洁的方式执行此操作(无需额外的努力、实体等)。如果那不可能——而且看起来不可能——那么我会以最简单的方式进行调整。在这种情况下,通过将 API 调用移至 afterSave() 回调,我可以避免管理任何额外的数据。不是我的完美世界,但它就足够了。 :-) 谢谢。
  • 这个问题已经持续了很长时间,我认为可以公平地假设它是不可能的(至少在 1.2.x 中)。我将把它标记为答案,因为它是一个可靠的解决方法。我实际上做的是颠倒调用顺序——本地保存第一,远程保存第二。如果远程保存失败,我会回滚本地保存。
【解决方案2】:

有一种方法——但通常你会在用户表中添加另一列,然后让 CakePHP 用主键来做这件事。请参阅此Bakery article 以了解它是如何完成的。由于是一年多之后的事情,所以主要是作为参考。据我了解,这在 CakePHP 1.2 中应该也能正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多