2017-09-14 97 views
3

在我的代码中,我试图在调用控制器函数时创建一个锁定实体。一旦我创建新实体,我将其保存在数据库中。一旦控制器函数完成其逻辑的其余部分,我在返回重定向之前更新锁实体。但是,当我更新实体并再次保存时,它总会插入一个新的数据库行,而不是更新现有的实体。保存更新实体而不是插入

我到目前为止尝试过的东西。

  • 我打电话给$ entity-> isNew(false);
  • 我用find()方法更新之前获得实体和保存
  • 二手patchEntity方法之前保存()

这两种方法都应该更新是否新款()信号保存()来更新条目而不是插入一个新的条目,但是我总是会获得一个添加到数据库的新行。

这里是相关代码。

这是我的控制器功能

//Inside of edit function of controller 

$editLockTable = TableRegistry::get('TableLocks'); 
$editLock = newEntity($userId, $postId); 
$editLock->lock(); 
if(!$editLockTable->save($editLock)){ 
    Throw new \Exception("Error with saving lock"); 
} 
. 
. // Some other controller function code 
. 
$editLock->unlock(); 
$editLock->isNew(false); 
if(!editLockTable->save($editLock)){ 
    Throw new \Exception("Error with saving unlock"); 
} 
//return redirect 

这里里面的逻辑是我的实体类

//Inside of Entity class for EditLock 

public function lock($userId, $postId){ 
    $this->user_id = $userId; 
    $this->post_id = $postId; 
    $this->start_time = Time::now(); 
    $this->is_locked = true; 
    $this->expire_time = Time::now()->modify('+10 minutes'); 
} 

public function unlock(){ 
    $this->end_time = Time::now(); 
    $this->is_locked = false; 

edit_locks表定义内部的逻辑

CREATE TABLE 'edit_locks' (
    'id' int(11) NOT NULL AUTO_INCREMENT, 
    'post_id' int(11) NOT NULL, 
    'user_id' int(11) NOT NULL, 
    'is_locked' tinyint(1) DEFAULT '0', 
    'start_time' datetime DEFAULT '0000-00-00 00:00:00', 
    'end_time' datetime DEFAULT '0000-00-00 00:00:00', 
    'expires_time' datetime DEFAULT '0000-00-00 00:00:00', 
    'renews' int(11) DEFAULT 0, 
    PRIMARY KEY ('id'), 
    KEY 'fk_post_id' ('post_id'), 
    CONSTRAINT 'fk_post_id' FOREIGN KEY ('post_id') REFERENCES 'posts'('id') 
    ENGINE=InnoDB DEFAULT CHARSET=latin1 
) 

我在得到什么控制器功能完成后我的数据库

id|post_id|user_id|is_locked|start_time|end_time|expires_time|renews 
1 | 999 | 32 | 1 | 2017-09-14 ... | 0000-00-00 ... | 2017-09-14 ... | 0 
2 | 999 | 32 | 0 | 2017-09-14 ... | 2017-09-14 ... | 2017-09-14 ... | 0 

我想在我的数据库控制功能后,什么结束

id|post_id|user_id|is_locked|start_time|end_time|expires_time|renews 
1 | 999 | 32 | 0 | 2017-09-14 ... | 2017-09-14 ... | 2017-09-14 ... | 0 

与这两个is_locked和END_TIME更新,而不是一个新行

+0

检查您的实体是否为dirty(),如果没有使用setDirty()将一个字段标记为脏。 Table :: save()不会保存实体,因为它看起来没有变化。 – burzum

+0

所以我在场上设置了脏标志。在我的调试日志中,我可以看到isNew()== false和dirty == true,但是我仍然将单独的行插入表中,而不是更新。 – user2860682

+0

嘿,只是好奇,如果我的答案有所帮助,或者如果你仍然需要帮助。 – KaffineAddict

回答

1

你的主键被列为ID和你不设置那个地方看起来不像。如果您的主键不匹配,您将无法更新记录。为什么不做类似的事情。

$editLock = editLockTable->findByUserIdAndPostId($userId, $postId); 
if($editLock == null) { $editLock = newEntity($userId, $postId); } 

更好的是,你可以做一个findOrCreate调用以及让你在一次调用中处理这两种情况。如果找不到记录,findOrCreate将创建一个具有指定条件的实体。

相关问题