Welcome Guest, Not a member yet? Register   Sign In
Model files in CI4
#1

Hi,
I've started to develope my second project with Ci3, but now, after an upgrade to php 7.4, I got some errors, and I decided to rewrite everything in Ci4.
It's a big job, but the Ci4 Application Structure looks much more similar with the "right" MVC schema: I like it.
But there is something not clear to me in the documentation:
in the esample there is 1 model file, with 1 class, linking 1 DB table.
In my project there are more than 50 tables: must I make 1 model file per each table, or can I groupe all the [entity] classes (1 per table) in 2-3 files?
Where must I write the names of these files, in order to let them work?
Reply
#2

You can do it however you want! I generally make one model for every “class”, so if a table is something you would represent as an object then I model it, otherwise I simply access it using Query Builder.

With namespacing you can really put your files anywhere. There are advantages to placing them in the “Models” folder in each namespace (e.g. using Factories to access them) but as long as your namespace and folder structure match then the autoloader will find them.
Reply
#3

Controller model view seeder migration entity

All you need for ci4
Enlightenment  Is  Freedom
Reply
#4

Thanks for reply,
but I can't figure it out.
Example:
I have a DB table named AA_Tabella1.

My Entity file is Entities/E_Comuni.php:
<?php
namespace App\Entities;
use CodeIgniter\Entity\Entity;
class AA_Tabella1 extends Entity
{}

My model file is Models/M_Comuni.php:
<?php
namespace App\Models;
use CodeIgniter\Model;
class AA_Tabella1Model extends Model
{
protected $table = 'AA_Tabella1';
protected $returnType = 'App\Entities\AA_Tabella1';
protected $allowedFields = [];
public function Leggi($Lingua = 0)
{
if ($Lingua === 0)
{
$TabOut = $this->asObject()
->findAll();
}
else
{
$TabOut = $this->asObject()
->where(['Lingua' => $Lingua])
->first();
}
return $TabOut;
}
}

My Controller file is Controllers/Prova1:
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use App\Models\M_Comuni;
class Prova1 extends BaseController
{
public function index($Lingua = 'en')
{
$modello = new \App\Models\M_Comuni\AA_Tabella1Model();
$ListaLingue = $modello->Leggi();
$Dati['Lingua'] = $Lingua;
$Dati['ListaLingue'] = $ListaLingue;
echo view('pagprova2', $Dati);
}
}

The error I got is:
"Class 'App\Models\M_Comuni\AA_Tabella1Model' not found"

What is wrong?
Reply
#5

Class name must match file name. If not, the autoloader won’t find them and won’t know which file to load.
CodeIgniter 4 tutorials (EN/FR) - https://includebeer.com
Reply
#6

Also you need to define the allowedFields array with the fields you want returned.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#7

(This post was last modified: 07-13-2021, 03:30 AM by davis.lasis.)

Your files and code should look something like this:

Entities/ComuniEntity.php
PHP Code:
<?php
namespace App\Entities;

use 
CodeIgniter\Entity\Entity;

class 
ComuniEntity extends Entity
{
    protected $datamap = [];

    /**
    * Define properties that are automatically converted to Time instances.
    */
    protected $dates = ['updated_at''created_at'];

    /**
    * Array of field names and the type of value to cast them as
    * when they are accessed.
    */
    protected $casts = [];


Models/ComuniModel.php
PHP Code:
<?php
namespace App\Models;

use 
CodeIgniter\Model;
use 
App\Entities\ComuniEntity;

class 
ComuniModel extends Model
{
    protected $table 'AA_Tabella1';
    protected $returnType ComuniEntity::class;
    protected $allowedFields = ['column_1''column_2''column_3'];

    public function Leggi(string $Lingua ''
    {
        if (!empty($Lingua)) {
            return $this->where('Lingua'$Lingua)->first();
        }

        return $this->findAll();
    }


Controllers/Prova1.php
PHP Code:
<?php
namespace App\Controllers;

use 
CodeIgniter\Controller;
use 
App\Models\ComuniModel;

class 
Prova1 extends BaseController
{
    public function index(string $Lingua 'en')
    {
        $modello = new ComuniModel();

        $Dati = [
            'Lingua' => $Lingua,
            'ListaLingue' => $modello->Leggi($Lingua),
        ];

        echo view('pagprova2'$Dati);
    }



I hope this will help you to get one "module" going and to continue on other 49...ish
Reply
#8

Sorry, my english is not good, but the first and last answers seem inconsistent to me; maybe I was not clear or I misanderstood some answare.
I asked if I can gruope many entity declaration into one single file, and "MGatneg" replyed that I can (this way i understood).
Now "includebeer" says that "Class name must match file name" and "davis.lasis" answers according to this rule: it means one entity file per each entity class.
In my project there are 68 DB-Tables (AA_Tabella1, AA_Tabella2... AA_Tabella68): does this mean that I must make 68 Entity files, 68 Model Files and [above all] a 68-line header in each Controller?
Reply
#9

A model can do select in multiple tables, but you will need to write the query yourself, you won't benefit from most of the features the Model class has to offer. You can also not have any entities at all and just use generic objects or arrays. But then again, you won't benefit from the Entity class. Also, with a project that large, the code will quickly become an unmaintainable mess. I doubt that your controller will access all 68 tables every time! Maybe you need to create separate controllers for different part of your application. You can also create some libraries that do the heavy lifting and keep your controller small. Maybe take a look at how I did it in this tutorial. This is just one way to do it. You can choose the way you prefer. But when you have a big application, it's important to have a good structure or else it becomes harder to maintain and develop further.
CodeIgniter 4 tutorials (EN/FR) - https://includebeer.com
Reply
#10

Thankyou very much Includebeer.

I already had many controllers, multi-level libraries, models in my CI3 version.
The questions are:

1) I'm already grouping many tabel's data into big multi-table objects, i.e:
$GC->Tabella1, from AA_Tabella1,
$GC->Tabella2, from AA_Tabella2...
How can I replicate this in CI4?
1A) in the models, reading multiple tables and constructing there the multi-table objects?
or
1B) in some 0-level libraries, reading from CI4-standard single-tabel models?
Option "1B" can work if I can declare the used model in the library file header, instead of in the controller. May I?

2) $GC is declared "static" in the Controller. So I can handle it with the librarie's functions.
This will not change from CI3 to Ci4, right?

3) In each library I had this header:
protected $CI;
public function __construct()
{
// Assign the CodeIgniter super-object
$this->CI =& get_instance();
}
In this way I can use in the libraries the header of the controller.
How does it work/translate this in CI4?

4) In CI4 standard Model there is a Key declaration:
i.e: protected $primaryKey = 'id';
It assumes that the table has a single key.
90% of my tables have multiple keys, i.e. GameID, ItemID: can the standard CI4 models handle this?
Reply




Theme © iAndrew 2016 - Forum software by © MyBB