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);
$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
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.