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