Search code examples
modelentitiescodeigniter-4

$model->save() doesn't use entity


I am slowly learning version 4 of CodeIgniter and I stumble upon a strange behaviour:

When using the save() method of my model, it only saves the created_at and updated_at timestamps.

Here is the useful code.

Migration

public function up()
{
    $this->forge->addField('id');
    $this->forge->addField([
        'title' => [
            'type' => 'varchar',
            'constraint' => 127
        ],
        'content' => [
            'type' => 'text'
        ],
        'slug' => [
            'type' => 'varchar',
            'constraint' => 127
        ],
        'created_at' => [
            'type' => 'datetime'
        ],
        'updated_at' => [
            'type' => 'datetime'
        ],
        'deleted_at' => [
            'type' => 'datetime',
            'null' => true
        ]
    ]);
    $this->forge->createTable('articles');
}

NOTE: it works fine, the table is correctly created in the database, as you can see below.

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(9)       | NO   | PRI | NULL    | auto_increment |
| title      | varchar(127) | NO   |     | NULL    |                |
| content    | text         | NO   |     | NULL    |                |
| slug       | varchar(127) | NO   |     | NULL    |                |
| created_at | datetime     | NO   |     | NULL    |                |
| updated_at | datetime     | NO   |     | NULL    |                |
| deleted_at | datetime     | YES  |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

Entity

namespace App\Entities;

class Article
{
}

Model

namespace App\Models;

class ArticleModel extends \CodeIgniter\Model
{
    protected $table = 'articles';
    protected $returnType = 'App\Entities\Article';
    protected $allowedFields = ['title', 'content', 'slug'];
    protected $useTimestamps = true;
}

Calling the model

I tried calling the model from two different places: a seeder and a controller, using the code below.

$article = new \App\Entities\Article();
$article->title = 'Article Title';
$article->content = 'Article Content';

$model = new \App\Models\ArticleModel();
$model->save($article);
echo $model->getLastQuery();

Both times, the result was the same. The echo shows the following.

INSERT INTO `articles` (`created_at`, `updated_at`) VALUES ('2019-10-09 02:25:56', '2019-10-09 02:25:56')

I have no idea how to tell my model (I think it's the responsible for the bad behaviour) to take into account its $allowedFields to save the article.

Can you see the problem?


Solution

  • It turns out that the save() method of the model only accepts objects of the class CodeIgniter\Entitiy in that case.

    The good thing to do is to make Article extend that class:

    namespace App\Entities;
    
    class Article extends \CodeIgniter\Entitiy
    {
    }
    

    This solves the problem.