Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Model insert Created_at and updated_at get when new record added #2737

Closed
MisterAnmar opened this issue Mar 21, 2020 · 5 comments
Closed
Labels
bug Verified issues on the current code behavior or pull requests that will fix them

Comments

@MisterAnmar
Copy link

MisterAnmar commented Mar 21, 2020

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

  • OS: Win10
  • Web server WAMP 3.1.9 64bit
  • PHP version 7.3.5
    ---------- an Update
    MySQL version 5.7.26
@MisterAnmar MisterAnmar added the bug Verified issues on the current code behavior or pull requests that will fix them label Mar 21, 2020
@akbarabustang
Copy link

is anyone working on this issue?

@MGatner
Copy link
Member

MGatner commented Mar 23, 2020

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.

@MisterAnmar
Copy link
Author

MisterAnmar commented Mar 24, 2020

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

@a91287
Copy link

a91287 commented Apr 10, 2020

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 :
`<?php namespace App\Entities;

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.

@a91287
Copy link

a91287 commented Apr 10, 2020

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 :
`<?php namespace App\Entities;

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Verified issues on the current code behavior or pull requests that will fix them
Projects
None yet
Development

No branches or pull requests

5 participants