douyan9417 2017-09-14 16:45
浏览 36
已采纳

在保存而不是插入时更新实体

In my code I am trying to create a lock entity when a controller function is called. Once I create the new entity I save this in the database. Once the controller function finishes the rest of its logic I update the lock entity before I return the redirect. However when I update the entity and then save again it will always insert a new database row rather than update the existing entity.

Things I have tried so far.

  • I called $entity->isNew(false);
  • I used find() method to get entity before update and save
  • Used patchEntity method before save()

Both of these methods should update isNew() to signal save() to update the entry rather than insert a new entry, however I am always getting a new row added to the database.

Here is the relavent code.

This is the logic inside of my controller function

//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

Here is the logic inside my Entity class

//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 table definition

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
)

What I am getting in my database after controller function finishes

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

What I want in my database after controller function finishes

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

With both is_locked and end_time updated and not a new row

  • 写回答

1条回答 默认 最新

  • duanchi8112 2017-09-22 14:30
    关注

    Your primary key is listed as ID and you are not setting that anywhere it doesn't look like. If your primary key doesn't match you will not be able to update a record. Why not do something like.

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

    Better yet you could do a findOrCreate call as well that would let you handle both situations in one call. findOrCreate will create an entity with the specified conditions if a record is not found.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥60 pb数据库修改或者求完整pb库存系统,需为pb自带数据库
  • ¥15 spss统计中二分类变量和有序变量的相关性分析可以用kendall相关分析吗?
  • ¥15 拟通过pc下指令到安卓系统,如果追求响应速度,尽可能无延迟,是不是用安卓模拟器会优于实体的安卓手机?如果是,可以快多少毫秒?
  • ¥20 神经网络Sequential name=sequential, built=False
  • ¥16 Qphython 用xlrd读取excel报错
  • ¥15 单片机学习顺序问题!!
  • ¥15 ikuai客户端多拨vpn,重启总是有个别重拨不上
  • ¥20 关于#anlogic#sdram#的问题,如何解决?(关键词-performance)
  • ¥15 相敏解调 matlab
  • ¥15 求lingo代码和思路