CodeIgniter CRUD Operations

CRUD stands for Create, Read, Update, and Delete — the four basic operations almost every data-driven feature boils down to. You've already met the individual Model methods that power each operation on the Models & Query Builder page; this page wires all four together into one complete, realistic controller so you can see the full request-to-database-and-back flow in one place.

1. Create

Creating a new row means calling insert() with an associative array of column values. Only keys listed in the Model's $allowedFields are actually written, which is your protection against mass-assignment:

$model = new \App\Models\ArticleModel();

$model->insert([
    'title'   => $title,
    'content' => $content,
    'status'  => 'draft',
]);

An alternative is save($data), a convenience method that inspects the array you pass it: if it looks like a new record it inserts, and if it already contains the primary key it updates the matching row instead. Many developers prefer keeping insert() and update() explicit and separate, as this page does, since it makes the controller's intent obvious at a glance.

2. Read

Reading covers three common shapes: one row by its ID, every row, or rows matching some filter.

// One row, by primary key
$article = $model->find($id);

// Every row
$articles = $model->findAll();

// One row, filtered by something other than the primary key
$article = $model->where('slug', $slug)->first();

find($id) and findAll() come straight from the base Model, while chaining where() before first() uses the Query Builder to fetch a single row matched by any column — first() simply returns the first matching row or null if none matched, instead of an array of results.

3. Update

Updating an existing row passes the primary key and the changed fields to update(). As with insert(), only allowed fields are actually written:

$model->update($id, [
    'title'   => $title,
    'content' => $content,
]);

4. Delete

Deleting a row only needs its primary key:

$model->delete($id);
Note: By default CodeIgniter Models perform a "soft delete" only if the Model defines $useSoftDeletes = true and a deleted_at column — otherwise delete() removes the row permanently. Check your Model's configuration before assuming deleted rows can be recovered.

5. A Complete Worked Example: the Articles Controller

Here is a full Articles controller demonstrating all four operations end-to-end, along with the routes that would point to each method. This follows the same controller structure introduced on the Controllers page and renders the views described on the Views page.

app/Config/Routes.php (relevant excerpt)

$routes->get('articles/create', 'Articles::create');
$routes->post('articles', 'Articles::store');
$routes->get('articles/(:num)/edit', 'Articles::edit/$1');
$routes->post('articles/(:num)', 'Articles::update/$1');
$routes->post('articles/(:num)/delete', 'Articles::delete/$1');

app/Controllers/Articles.php

<?php

namespace App\Controllers;

use App\Models\ArticleModel;

class Articles extends BaseController
{
    // GET /articles/create — show an empty form
    public function create()
    {
        return view('articles/create');
    }

    // POST /articles — save the submitted form (Create)
    public function store()
    {
        $model = new ArticleModel();

        $id = $model->insert([
            'title'   => $this->request->getPost('title'),
            'content' => $this->request->getPost('content'),
        ]);

        // getInsertID() returns the primary key of the row just inserted
        $newId = $model->getInsertID();

        return redirect()->to('/articles/' . $newId);
    }

    // GET /articles/{id}/edit — show a pre-filled form (Read for editing)
    public function edit($id)
    {
        $model = new ArticleModel();
        $data['article'] = $model->find($id);

        return view('articles/edit', $data);
    }

    // POST /articles/{id} — save changes (Update)
    public function update($id)
    {
        $model = new ArticleModel();

        $model->update($id, [
            'title'   => $this->request->getPost('title'),
            'content' => $this->request->getPost('content'),
        ]);

        return redirect()->to('/articles/' . $id);
    }

    // POST /articles/{id}/delete — remove the row (Delete)
    public function delete($id)
    {
        $model = new ArticleModel();
        $model->delete($id);

        return redirect()->to('/articles');
    }
}

Every route maps to exactly one controller method, each method uses exactly one Model call to talk to the database, and each method finishes either by rendering a view or issuing a redirect. That round trip — route, controller, Model, and view or redirect — is the complete request lifecycle for almost any CRUD-driven feature in CodeIgniter.

6. Retrieving the Last Inserted ID

After calling insert(), you frequently need the primary key of the row that was just created — for example, to redirect the user straight to that new article's page, as the store() method above does. The Model's getInsertID() method returns exactly that:

$model->insert(['title' => 'New Article']);
$newId = $model->getInsertID();

// $newId now holds the auto-incremented primary key of that new row
Tip: insert() itself already returns the new ID when it succeeds (as used for $id earlier in this page), so calling getInsertID() separately is most useful when you need the ID again later in the same method, after other code has run.
Next: With full CRUD in place, continue with Helpers & Libraries to see the reusable utility functions and service classes CodeIgniter provides beyond the MVC core.