【问题标题】:Can't update (but create new) objects in CakePHP with save()无法使用 save() 在 CakePHP 中更新(但创建新的)对象
【发布时间】:2014-05-02 12:08:01
【问题描述】:

在 LAMP 设置(Ubuntu 13.10、Apache 2、MySQL Server 5.5、PHP 5.5.3)上使用 CakePHP 2.4.9。

试图将模型(用户)打包到插件中,但我遇到了一个奇怪的问题:

在两个不同的操作中,我使用save() 创建或更新用户。这有效:

if ($this->request->data) {

    if ($this->User->create() && $this->User->save($this->request->data)) {
        $this->Session->setFlash(_('<strong>Congratulations!</strong> Successfully created a new user.'), 'default', array('class' => 'alert alert-success'));
        $this->redirect(array('action' => 'register'));
    } else {
        $this->Session->setFlash(_('<strong>Oops!</strong> Could not create a new user.'), 'default', array('class' => 'alert alert-danger'));
    }
}

但这不起作用:

if ($this->request->data) {

    $this->User->id = $id;

    if ($this->User->save($this->request->data)) {
        $this->Session->setFlash(_('<strong>Congratulations!</strong> Successfully updated your user account.'), 'default', array('class' => 'alert alert-success'));
        $this->redirect(array('action' => 'settings'));
    } else {
        $this->Session->setFlash(_('<strong>Oops!</strong> Could not update user account.'), 'default', array('class' => 'alert alert-danger'));
    }
}

当我尝试保存后一个示例(“更新操作”)时,出现以下错误:

致命错误

错误:在非对象上调用成员函数 getColumnType() 文件:/home/johan/sites/userplugin/lib/Cake/Model/Model.php 线路:1412

注意:如果要自定义此错误信息,请创建 app/View/Errors/fatal_error.ctp

表单非常标准,我使用FormHelper 创建表单和字段。但在更新表单中,我有一个带有 ID 的隐藏字段:

<?php echo $this->Form->hidden('id'); ?>

如果我删除它,更新表单会通过但会创建一个新对象!所以就像$this-&gt;User-&gt;id = $id 什么都不做。我目前设置$id“手动”,所以$id = 1...

我尝试搜索类似的问题,但没有找到任何东西。一个讨论提到了 ID 字段,也许它没有正确设置?但我找不到任何解决方案。

【问题讨论】:

  • Cake 不应该使用ID 而不是id(区分大小写)吗?
  • 不这么认为。手册说://更新:id设置为数值$this->Recipe->id = 2; $this->recipe->save($this->request->data); Link to manual
  • 我的错误,ID 在其他框架中。对不起:)
  • 错误消息表明您的模型关联可能有问题。另请注意,如果 ID 已经通过数据传递,则无需设置 ID,理想情况下主键列应自动递增。
  • 我没有任何关联的模型。这可能与模型是插件的一部分有关吗?认为我可能在某处引用错误,这使得 CakePHP 假设 User 是“应用程序空间”的一部分? id字段是AI,不管我是通过表单数据传递id还是用$this->User->id设置...

标签: php mysql cakephp cakephp-2.4


【解决方案1】:

有一个错误的模型参考

不同的代码排列与问题没有直接 - 或者可能只是表示另一个不同的问题 =)。

line of code that is failing 是这样的:

$this->{$model}->getColumnType($column);

其中$this 是用户模型实例。 可能的意思是,当它失败时,对象不是你期望检查的类:

debug(get_class($this->User));

在您的控制器中,很可能是AppModel

是什么原因造成的

这种“有时有效,有时无效”问题的典型原因是使用插件前缀对模型的一些引用,而有些则不是。

<?php

App::uses('MyPluginAppModel', 'MyPlugin.Model');

class Group extends MyPluginAppModel {

    public $hasMany = array(
        'User' => array(
            'className' => 'User'
        ),
        #'User' # Or like this
    )

}

应该是这样的:

<?php

App::uses('MyPluginAppModel', 'MyPlugin.Model');

class Group extends MyPluginAppModel {

    public $hasMany = array(
        'User' => array(
            'className' => 'MyPlugin.User'
        ),
        #'MyPlugin.User' # Or like this
    )

}

这里发生的情况取决于第一次访问相关模型的方式,以及在类注册表中填充 User 键的内容以及为该模型引用的所有后续请求返回的内容。

要解决此问题,请确保始终使用正确的插件前缀引用模型(如果它不是插件模型,则当然没有前缀)。

【讨论】:

  • 感谢您的回答!看来您的钱是对的,不幸的是,我似乎找不到任何直接指向User而不是MyPlugin.User的类名引用,所以我仍然卡住了。有趣的是,当我调试时getColumnType() $model 没有设置,即'#0 /home/johan/sites/userplugin/lib/Cake/Model/Datasource/DboSource.php(1877): Model-&gt;getColumnType('id') # FAILS! $model == NULL'#0 /home/johan/sites/userplugin/lib/Cake/Model/Datasource/DboSource.php(2563): Model-&gt;getColumnType('User.id') # WORKS! $model == 'User'
  • debug(get_class($this-&gt;User)) 在我的 UsersController 中返回 'User'。当我调试整个 $this-&gt;User 对象时,它似乎是正确的(属于我的插件的“用户”模型)。
  • 感谢您的帮助,我刚刚用一些输出和类更新了第一篇文章。我希望我做对了。
  • 你说得对,现在这个问题有点泛滥。我会尝试清理它。反正。如果我将调试函数放在 if 语句中,在 return $this-&gt;{$model}-&gt;getColumnType($column); 之前它不会显示任何堆栈跟踪!除非我运行die;,它实际上给了我一些东西...嗯$model == userplugin...
  • AD7,我找到了导致问题的原因,并用“解决方案”更新了原始问题。但是,由于您的回答确实指出了一些潜在问题,因此我将其标记为“已接受”。感谢您的帮助!
【解决方案2】:

我最终发现(并且应该早点排除,真的)是在我的AppModel 中定义了一个用于配置插件的数组,与我的插件命名相同是愚蠢的,也许是边缘智障。

即如果您的插件名为 MyPlugin,请不要在 AppModel 中定义 $myplugin 数组。

【讨论】:

    【解决方案3】:

    试试这个

    //控制器

    public function edit(){ 
    
        if (!empty($this->request->data)) {
    
            //if you want to save on User object
             $this->User->id = $this->request->data['User']['id'];
    
            if ($this->User->save($this->request->data)) {
            .................................
                $this->Session->setFlash(_('<strong>Congratulations!</strong> Successfully updated your user account.'), 'default', array('class' => 'alert alert-success'));
                $this->redirect(array('action' => 'settings'));
            } else {
                $this->Session->setFlash(_('<strong>Oops!</strong> Could not update user account.'), 'default', array('class' => 'alert alert-danger'));
            }
        } else {
           $this->request->data = $this->User->read(null, $id);
        }
    }
    

    //编辑视图

    <?php 
    echo $this->Form->create('User'); 
    echo $this->Form->hidden('id'); 
    echo $this->Form->input('first_name'); 
    ..
    ..
    .  
    echo $this->Form->end(__('Save')); 
    ?>
    

    【讨论】:

    • 抱歉并不是粗鲁——但我真的不明白你在说什么?
    • 呃...是的,我愿意。但我不确定你是否理解了我的问题?这不是使用save() 的基础,而是这个特定的问题。
    • 您没有在函数顶部设置 $id 值。刚刚更新了我的答案
    猜你喜欢
    • 1970-01-01
    • 2016-06-22
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-20
    • 2023-03-15
    相关资源
    最近更新 更多