PHPackages                             yidas/codeigniter-model - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. yidas/codeigniter-model

ActiveLibrary[Database &amp; ORM](/categories/database)

yidas/codeigniter-model
=======================

CodeIgniter 3 ORM Base Model pattern with My\_model example

2.19.3(2y ago)17212.0k↓50%47[5 issues](https://github.com/yidas/codeigniter-model/issues)2MITPHPPHP &gt;=5.4.0

Since Dec 19Pushed 2y ago9 watchersCompare

[ Source](https://github.com/yidas/codeigniter-model)[ Packagist](https://packagist.org/packages/yidas/codeigniter-model)[ Docs](https://github.com/yidas/codeigniter-model)[ RSS](/packages/yidas-codeigniter-model/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)DependenciesVersions (49)Used By (2)

 [ ![](https://camo.githubusercontent.com/7040d7395e52bcf95f4482b9ad6d5ca99fa7340041694e6885835ea2bd0a38c3/68747470733a2f2f636f646569676e697465722e636f6d2f6173736574732f69636f6e732f63692d6c6f676f2e706e67) ](https://codeigniter.com/userguide3/)

CodeIgniter Model
=================

[](#codeigniter-model)

CodeIgniter 3 Active Record (ORM) Standard Model supported Read &amp; Write Connections

[![Latest Stable Version](https://camo.githubusercontent.com/b6ae17eb2656f72af7fad679ca33a8dcc5be688f9f4898068505463e99327242/68747470733a2f2f706f7365722e707567782e6f72672f79696461732f636f646569676e697465722d6d6f64656c2f762f737461626c653f666f726d61743d666c61742d737175617265)](https://packagist.org/packages/yidas/codeigniter-model)[![License](https://camo.githubusercontent.com/d9a196ad55a86ecd591c317bf1db726969d6a77eb012f2fcc85efff0673b3eec/68747470733a2f2f706f7365722e707567782e6f72672f79696461732f636f646569676e697465722d6d6f64656c2f6c6963656e73653f666f726d61743d666c61742d737175617265)](https://packagist.org/packages/yidas/codeigniter-model)

This ORM Model extension is collected into [yidas/codeigniter-pack](https://github.com/yidas/codeigniter-pack) which is a complete solution for Codeigniter framework.

FEATURES
--------

[](#features)

- ***[ORM](#active-record-orm)** Model with **Elegant patterns** as Laravel Eloquent ORM &amp; Yii2 Active Record*
- ***[CodeIgniter Query Builder](#find)** integration*
- ***[Timestamps Behavior](#timestamps)** &amp; **[Validation](#validation)** &amp; **[Soft Deleting](#soft-deleted)** &amp; **[Query Scopes](#query-scopes)** support*
- ***[Read &amp; Write Splitting](#read--write-connections)** for Replications*

This package provide Base Model which extended `CI_Model` and provided full CRUD methods to make developing database interactions easier and quicker for your CodeIgniter applications.

OUTLINE
-------

[](#outline)

- [Demonstration](#demonstration)
- [Requirements](#requirements)
- [Installation](#installation)
- [Configuration](#configuration)
- [Defining Models](#defining-models)
    - [Table Names](#table-names)
    - [Primary Keys](#primary-keys)
    - [Timestamps](#timestamps)
    - [Database Connection](#database-connection)
    - [Other settings](#other-settings)
- [Basic Usage](#basic-usage)
    - [Methods](#methods)
        - [find()](#find)
            - [Query Builder Implementation](#query-builder-implementation)
        - [reset()](#reset)
        - [insert()](#insert)
        - [batchInsert()](#batchinsert)
        - [update()](#update)
        - [batchUpdate()](#batchupdate)
        - [replace()](#replace)
        - [delete()](#delete)
        - [getLastInsertID()](#getlastinsertid)
        - [getAffectedRows()](#getaffectedrows)
        - [count()](#count)
        - [setAlias()](#setalias)
- [Active Record (ORM)](#active-record-orm)
    - [Inserts](#inserts)
    - [Updates](#updates)
    - [Deletes](#deletes)
    - [Accessing Data](#accessing-data)
    - [Relationships](#relationships)
    - [Methods](#methods-1)
        - [findone()](#findone)
        - [findAll()](#findall)
        - [save()](#save)
        - [beforeSave()](#beforesave)
        - [afterSave()](#afterave)
        - [hasOne()](#hasone)
        - [hasMany()](#hasmany)
        - [toArray()](#toarray)
- [Soft Deleted](#soft-deleted)
    - [Configuration](#configuration-1)
    - [Methods](#method-2)
- [Query Scopes](#query-scopes)
    - [Configuration](#configuration-2)
    - [Methods](#method-3)
- [Validation](#validation)
    - [Validating Input](#validating-input)
        - [validate()](#validate)
        - [getErrors()](#geterrors)
    - [Declaring Rules](#declaring-rules)
        - [rules()](#rules)
        - [Error Message with Language](#error-message-with-language)
    - [Filters](#filters)
        - [Filters()](#filters-1)
- [Read &amp; Write Connections](#read--write-connections)
    - [Configuration](#configuration-3)
    - [Load Balancing for Databases](#load-balancing-for-databases)
    - [Reconnection](#reconnection)
- [Pessimistic Locking](#pessimistic-locking)
- [Helpers](#helpers)
    - [indexBy()](#indexby)

---

DEMONSTRATION
-------------

[](#demonstration)

### ActiveRecord (ORM)

[](#activerecord-orm)

```
$this->load->model('Posts_model');

// Create an Active Record
$post = new Posts_model;
$post->title = 'CI3'; // Equivalent to `$post['title'] = 'CI3';`
$post->save();

// Update the Active Record found by primary key
$post = $this->Posts_model->findOne(1);
if ($post) {
    $oldTitle = $post->title; // Equivalent to `$oldTitle = $post['title'];`
    $post->title = 'New CI3';
    $post->save();
}
```

> The pattern is similar to [Yii2 Active Record](https://www.yiiframework.com/doc/guide/2.0/en/db-active-record#active-record) and [Laravel Eloquent](https://laravel.com/docs/5.8/eloquent#inserting-and-updating-models)

### Find with Query Builder

[](#find-with-query-builder)

Start to use CodeIgniter Query Builder from `find()` method, the Model will automatically load its own database connections and data tables.

```
$records = $this->Posts_model->find()
    ->select('*')
    ->where('is_public', '1')
    ->limit(25)
    ->order_by('id')
    ->get()
    ->result_array();
```

### CRUD

[](#crud)

```
$result = $this->Posts_model->insert(['title' => 'Codeigniter Model']);

// Find out the record which just be inserted
$record = $this->Posts_model->find()
  ->order_by('id', 'DESC')
  ->get()
  ->row_array();

// Update the record
$result = $this->Posts_model->update(['title' => 'CI3 Model'], $record['id']);

// Delete the record
$result = $this->Posts_model->delete($record['id']);
```

---

REQUIREMENTS
------------

[](#requirements)

This library requires the following:

- PHP 5.4.0+
- CodeIgniter 3.0.0+

---

INSTALLATION
------------

[](#installation)

Run Composer in your Codeigniter project under the folder `\application`:

```
composer require yidas/codeigniter-model

```

Check Codeigniter `application/config/config.php`:

```
$config['composer_autoload'] = TRUE;
```

> You could customize the vendor path into `$config['composer_autoload']`

---

CONFIGURATION
-------------

[](#configuration)

After installation, `yidas\Model` class is ready to use. Simply, you could create a model to extend the `yidas\Model` directly:

```
class Post_model extends yidas\Model {}
```

After that, this model is ready to use for example: `$this->PostModel->findOne(123);`

However, the schema of tables such as primary key in your applicaiton may not same as default, and it's annoying to defind repeated schema for each model. We recommend you to make `My_model` to extend `yidas\Model` instead.

### Use My\_model to Extend Base Model for every Models

[](#use-my_model-to-extend-base-model-for-every-models)

You could use `My_model` to extend `yidas\Model`, then make each model to extend `My_model` in Codeigniter application.

*1. Create `My_model` extended `yidas\Model` with configuration for fitting your common table schema:*

```
class My_model extends yidas\Model
{
    protected $primaryKey = 'sn';
    const CREATED_AT = 'created_time';
    const UPDATED_AT = 'updated_time';
    // Customized Configurations for your app...
}
```

*2. Create each Model extended `My_model` in application with its own table configuration:*

```
class Post_model extends My_model
{
    protected $table = "post_table";
}
```

*3. Use each extended Model with library usages:*

```
$this->load->model('post_model', 'PostModel');

$post = $this->PostModel->findOne(123);
```

[My\_model Example with Document](https://github.com/yidas/codeigniter-model/tree/master/example)

---

DEFINING MODELS
---------------

[](#defining-models)

To get started, let's create an model extends `yidas\Model` or through `My_model`, then define each model suitably.

### Table Names

[](#table-names)

By convention, the "snake case" with lowercase excluded `_model` postfix of the class name will be used as the table name unless another name is explicitly specified. So, in this case, Model will assume the `Post_model` model stores records in the `post` table. You may specify a custom table by defining a table property on your model:

```
// class My_model extends yidas\Model
class Post_model extends My_model
{
    protected $table = "post_table";
}
```

> You could set table alias by defining `protected $alias = 'A1';` for model.

#### Table Name Guessing Rule

[](#table-name-guessing-rule)

In our pattern, The naming between model class and table is the same, with supporting no matter singular or plural names:

Model Class NameTable NamePost\_modelpostPosts\_modelpostsUser\_info\_modeluser\_info#### Get Table Name

[](#get-table-name)

You could get table name from each Model:

```
$tableName = $this->PostModel->getTable();
```

### Primary Keys

[](#primary-keys)

You may define a protected `$primaryKey` property to override this convention:

```
class My_model extends yidas\Model
{
    protected $primaryKey = "sn";
}
```

> Correct primary key setting of Model is neceesary for Active Record (ORM).

### Timestamps

[](#timestamps)

By default, Model expects `created_at` and `updated_at` columns to exist on your tables. If you do not wish to have these columns automatically managed by base Model, set the `$timestamps` property on your model as `false`:

```
class My_model extends yidas\Model
{
    protected $timestamps = false;
}
```

If you need to customize the format of your timestamps, set the `$dateFormat` property on your model. This property determines how date attributes are stored in the database:

```
class My_model extends yidas\Model
{
    /**
     * Date format for timestamps.
     *
     * @var string unixtime(946684800)|datetime(2000-01-01 00:00:00)
     */
    protected $dateFormat = 'datetime';
}
```

If you need to customize the names of the columns used to store the timestamps, you may set the `CREATED_AT` and `UPDATED_AT` constants in your model:

```
class My_model extends yidas\Model
{
    const CREATED_AT = 'created_time';
    const UPDATED_AT = 'updated_time';
}
```

Also, you could customized turn timestamps behavior off for specified column by assigning as empty:

```
class My_model extends yidas\Model
{
    const CREATED_AT = 'created_time';
    const UPDATED_AT = NULL;
}
```

### Database Connection

[](#database-connection)

By default, all models will use the default database connection `$this->db` configured for your application. If you would like to specify a different connection for the model, use the `$database` property:

```
class My_model extends yidas\Model
{
    protected $database = 'database2';
}
```

> More Database Connection settings: [Read &amp; Write Connections](#read--write-connections)

### Other settings

[](#other-settings)

```
class My_model extends yidas\Model
{
    // Enable ORM property check for write
    protected $propertyCheck = true;
}
```

---

BASIC USAGE
-----------

[](#basic-usage)

Above usage examples are calling Models out of model, for example in controller:

```
$this->load->model('post_model', 'Model');
```

If you call methods in Model itself, just calling `$this` as model. For example, `$this->find()...` for `find()`;

### Methods

[](#methods)

#### `find()`

[](#find)

Create an existent CI Query Builder instance with Model features for query purpose.

```
public CI_DB_query_builder find(boolean $withAll=false)
```

*Example:*

```
$records = $this->Model->find()
    ->select('*')
    ->where('is_public', '1')
    ->limit(25)
    ->order_by('id')
    ->get()
    ->result_array();
```

```
// Without any scopes & conditions for this query
$records = $this->Model->find(true)
    ->where('is_deleted', '1')
    ->get()
    ->result_array();

// This is equal to find(true) method
$this->Model->withAll()->find();
```

> After starting `find()` from a model, it return original `CI_DB_query_builder` for chaining. The query builder could refer [CodeIgniter Query Builder Class Document](https://www.codeigniter.com/userguide3/database/query_builder.html)

##### Query Builder Implementation

[](#query-builder-implementation)

You could assign Query Builder as a variable to handle add-on conditions instead of using `$this->Model->getBuilder()`.

```
$queryBuilder = $this->Model->find();
if ($filter) {
    $queryBuilder->where('filter', $filter);
}
$records = $queryBuilder->get()->result_array();
```

#### `reset()`

[](#reset)

reset an CI Query Builder instance with Model.

```
public self reset()
```

*Example:*

```
$this->Model->reset()->find();
```

#### `insert()`

[](#insert)

Insert a row with Timestamps feature into the associated database table using the attribute values of this record.

```
public boolean insert(array $attributes, $runValidation=true)
```

*Example:*

```
$result = $this->Model->insert([
    'name' => 'Nick Tsai',
    'email' => 'myintaer@gmail.com',
]);
```

#### `batchInsert()`

[](#batchinsert)

Insert a batch of rows with Timestamps feature into the associated database table using the attribute values of this record.

```
public integer batchInsert(array $data, $runValidation=true)
```

*Example:*

```
$result = $this->Model->batchInsert([
     ['name' => 'Nick Tsai', 'email' => 'myintaer@gmail.com'],
     ['name' => 'Yidas', 'email' => 'service@yidas.com']
]);
```

#### `replace()`

[](#replace)

Replace a row with Timestamps feature into the associated database table using the attribute values of this record.

```
public boolean replace(array $attributes, $runValidation=true)
```

*Example:*

```
$result = $this->Model->replace([
    'id' => 1,
    'name' => 'Nick Tsai',
    'email' => 'myintaer@gmail.com',
]);
```

#### `update()`

[](#update)

Save the changes with Timestamps feature to the selected record(s) into the associated database table.

```
public boolean update(array $attributes, array|string $condition=NULL, $runValidation=true)
```

*Example:*

```
$result = $this->Model->update(['status'=>'off'], 123)
```

```
// Find conditions first then call again
$this->Model->find()->where('id', 123);
$result = $this->Model->update(['status'=>'off']);
```

```
// Counter set usage equal to `UPDATE mytable SET count = count+1 WHERE id = 123`
$this->Model->getDB()->set('count','count + 1', FALSE);
$this->Model->find()->where('id', 123);
$result = $this->Model->update([]);
```

> Notice: You need to call `update` from Model but not from CI-DB builder chain, the wrong sample code:
>
> `$this->Model->find()->where('id', 123)->update('table', ['status'=>'off']);`

#### `batchUpdate()`

[](#batchupdate)

Update a batch of update queries into combined query strings.

```
public integer batchUpdate(array $dataSet, boolean $withAll=false, interger $maxLength=4*1024*1024, $runValidation=true)
```

*Example:*

```
$result = $this->Model->batchUpdate([
    [['title'=>'A1', 'modified'=>'1'], ['id'=>1]],
    [['title'=>'A2', 'modified'=>'1'], ['id'=>2]],
]);
```

#### `delete()`

[](#delete)

Delete the selected record(s) with Timestamps feature into the associated database table.

```
public boolean delete(array|string $condition=NULL, boolean $forceDelete=false, array $attributes=[])
```

*Example:*

```
$result = $this->Model->delete(123)
```

```
// Find conditions first then call again
$this->Model->find()->where('id', 123);
$result = $this->Model->delete();
```

```
// Force delete for SOFT_DELETED mode
$this->Model->delete(123, true);
```

#### `getLastInsertID()`

[](#getlastinsertid)

Get the insert ID number when performing database inserts.

*Example:*

```
$result = $this->Model->insert(['name' => 'Nick Tsai']);
$lastInsertID = $this->Model->getLastInsertID();
```

#### `getAffectedRows()`

[](#getaffectedrows)

Get the number of affected rows when doing “write” type queries (insert, update, etc.).

```
public integer|string getLastInsertID()
```

*Example:*

```
$result = $this->Model->update(['name' => 'Nick Tsai'], 32);
$affectedRows = $this->Model->getAffectedRows();
```

#### `count()`

[](#count)

Get count from query

```
public integer count(boolean $resetQuery=true)
```

*Example:*

```
$result = $this->Model->find()->where("age
