Describe the bug
When i use model->save() to insert new record
when using Maria DB everything fine
When i use mySQL it seems the model add the timestamp for created_at and updated_at.
which is strange it could be only me.
CodeIgniter 4 version
Appstarter using composer 4.0.2
Affected module(s)
Model Class
Context
is anyone working on this issue?
I'm unclear what the actual problem is. @anmar-dev could you share some example code from your Model and the call to save(), as well as database table structures and sample results from MariaDB and MySQL? All that would help determining if there is a problem and how to fix it.
Sure thing @MGatner .
Table structure.
`
CREATE TABLE `survey` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` BIGINT(20) UNSIGNED NOT NULL,
`title` VARCHAR(250) NOT NULL COLLATE 'utf8mb4_unicode_ci',
`description` VARCHAR(250) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`created_at` DATETIME NOT NULL,
`updated_at` DATETIME NULL DEFAULT NULL,
`deleted_at` DATETIME NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
)
COMMENT='stores surveys and who owns it.'
COLLATE='utf8mb4_unicode_ci'
ENGINE=InnoDB
AUTO_INCREMENT=16;
`
Model Code.
`
<?php namespace App\Models;
use CodeIgniter\Model;
class SurveyModel extends Model
{
protected $table = 'survey';
protected $primaryKey = 'id';
protected $returnType = 'array';
protected $useSoftDeletes = false;
protected $allowedFields = ['title', 'description', 'user_id'];
protected $useTimestamps = true;
protected $createdField = 'created_at';
protected $updatedField = 'updated_at';
protected $deletedField = 'deleted_at';
protected $validationRules = [
'title' => 'required|alpha_numeric_punct|min_length[3]',
'description' => 'permit_empty|alpha_numeric_punct',
'user_id' => 'required|integer'
];
protected $validationMessages = [];
protected $skipValidation = false;
}
`
and finally controller code.
`
public function create()
{
if ($this->request->getMethod() === 'post') {
$surModel = new SurveyModel();
$saveData = array_merge(['user_id' => session('user.user_id')],
$this->request->getPost());
if ($surModel->save($saveData)) {
session()->set('status', 'New Survey Added.');
return redirect()->to('/survey/fetch/'.$surModel->insertID());
}
session()->set('status', 'Fail Adding.');
session()->set('errors', $surModel->errors());
return redirect()->back()->withInput();
}
return view('sur_create', $this->data);
}
`
for further details please refer to the app repository SurveyIgniter
I got a similar issue, maybe the same, please find some details in regards to my findings:
Problem description:
When using an entity class, if you try to instantiate a model and use the save() method, it will populate the created_at and the updated_at fields incorrectly in the database tables:
Example:
Model Class:
`class UserModel extends Model
{
protected $db;
public function __construct()
{
try{
$this->db = \Config\Database::connect();
}
catch (Exception $e)
{
throw $e;
}
}
protected $table = 'users';
protected $primaryKey = 'id';
protected $returnType = 'array';
protected $useSoftDeletes = true;
protected $allowedFields = ['username', 'email', 'password'];
protected $useTimestamps = true;
protected $createdField = 'created_at';
protected $updatedField = 'updated_at';
protected $deletedField = 'deleted_at';
protected $validationRules = [];
protected $validationMessages = [];
protected $skipValidation = false;
function test(){
return 'test';
}
}
`
Entity class :
`
use CodeIgniter\Entity;
use App\Models\UserModel;
class UserEntity extends Entity
{
protected $attributes;
public function save()
{
try{
$u = new UserModel();
if (empty($this->attributes['id'])){
return $u->insert($this->attributes);
}
else{
return $u->update($this->attributes['id'],$this->attributes);
//return $u->save($this->attributes);
}
}
catch (\Exception $e){
throw $e;
}
}
}
`
Statement causing problems:
` try{
$u = new UserModel();
if (empty($this->attributes['id'])){
return $u->insert($this->attributes);
}
else{
**return $u->update($this->attributes['id'],$this->attributes);
//return $u->save($this->attributes);**
}
}
`
The code above will work on the first call to the save() method without an id specified in the attributes array. In this case, created_at and populated_at will be populated in the database with the same value which appears to be correct.
HOWEVER
If you get the generated ID and call the same method again passing the ID, whenever it updates or save the object, the created_at and updated_at will be populated where the created_at apparently gets a timestamp from "Chicago" and the updated_at gets the server local timestamp.
Hope it describes the problem.
Amauri.
I got a similar issue, maybe the same, please find some details in regards to my findings:
Problem description:
When using an entity class, if you try to instantiate a model and use the save() method, it will populate the created_at and the updated_at fields incorrectly in the database tables:Example:
Model Class:
`class UserModel extends Model
{protected $db; public function __construct() { try{ $this->db = \Config\Database::connect(); } catch (Exception $e) { throw $e; } } protected $table = 'users'; protected $primaryKey = 'id'; protected $returnType = 'array'; protected $useSoftDeletes = true; protected $allowedFields = ['username', 'email', 'password']; protected $useTimestamps = true; protected $createdField = 'created_at'; protected $updatedField = 'updated_at'; protected $deletedField = 'deleted_at'; protected $validationRules = []; protected $validationMessages = []; protected $skipValidation = false; function test(){ return 'test'; }}
`Entity class :
`use CodeIgniter\Entity;
use App\Models\UserModel;class UserEntity extends Entity
{
protected $attributes;public function save() { try{ $u = new UserModel(); if (empty($this->attributes['id'])){ return $u->insert($this->attributes); } else{ return $u->update($this->attributes['id'],$this->attributes); //return $u->save($this->attributes); } } catch (\Exception $e){ throw $e; } }}
`Statement causing problems:
` try{
$u = new UserModel();
if (empty($this->attributes['id'])){return $u->insert($this->attributes); } else{ **return $u->update($this->attributes['id'],$this->attributes); //return $u->save($this->attributes);** } }`
The code above will work on the first call to the save() method without an id specified in the attributes array. In this case, created_at and populated_at will be populated in the database with the same value which appears to be correct.
HOWEVER
If you get the generated ID and call the same method again passing the ID, whenever it updates or save the object, the created_at and updated_at will be populated where the created_at apparently gets a timestamp from "Chicago" and the updated_at gets the server local timestamp.
Hope it describes the problem.
Amauri.
This is not a problem with Codeigniter4 but a problem in the mysql table. In my case, I was using TIMESTAMP columns instead of DATETIME. By default MySQL does not allow null values in TIMESTAMP columns and will always assign a value to it automatically. To fix the problem I dropped the table and created it again with DATETIME columns.
Amauri.