My name is Stefan Ashwell and when I'm not coding personal projects or painting miniatures, I'm a Software Engineer at Holmes Media in Market Harborough.

This blog is a place for me to write about things that require that little bit extra to solve. We all have gaps in our knowledge and every now and then I need to reach out on search engines or blogs to find an answer. Often, these answers come from multiple sources. This blog serves as a personal resource, but if it's helpful for me I'm sure it'll help others too!

CodeIgniter Base Model

Posted on 14 September 2016

Why Use a Base Model?

I like to use a base model for common CRUD tasks that every model will need to perform. Rather than duplicating lots of code to retrieve database records this stuff can be written once and used by all of them.

Of course, some models might need something slightly different, which is fine – you can always overwrite any of the methods in your child models.

What Shall We Put in the Base Model?

For our base model, we have the following requirements:

  • The database table should be dynamic
  • It should provide methods for CRUD operations (Create, Edit, Update and Delete)

So let’s get started. The first thing we need to do is create our base model. We can do this in the application/core directory. Create a file here called MY_Model.php with the following boilerplate:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class MY_Model extends CI_Model {

}

One thing to note, the MY_ prefix on the file and class name is important. By doing this Codeigniter will allow us to use the base model. You can if you wish change this to any prefix you like in application/config/settings.php look for the following line:

$config['subclass_prefix'] = 'MY_';

Next, let’s write our methods. We’ll start off with a get method, which will return a single row from the database table:

public function get($value, $field = 'id') {

	$this->db->where($field, $value);
	$query	= $this->db->get($this->_table);
	$result	= $query->row_array();

	if ( count($result) > 0 ) {
		return $result;
	} else {
		return false;
	}

}

This method accepts two parameters; a value and a field. The most common usage of this function is to get an item by it’s id so we default the field to id for ease of use later, however by allowing us to supply any field to check against we make this get function very flexible. Imagine a situation where you have a users table, and each user has a slug that might be used to display their profile page. In some situations you will want to get a user’s information based on their id, and in order situations (like when someone visits their profile page) we would be getting their information based on their slug. This way we can re-use one method to achieve this, rather than writing two separate methods that essentially do the same thing.

Next we use Codeigniter’s query builder to build the query and execute it. See how we’re also using $this->_table in place of the database table name. This class variable will be set in your child model, to ensure we’re fetching results from the correct place.

Finally notice how we check to see if a result has been found before returning the record, and if not we return false. This can come in handy if you’re checking a record exists, the function makes things very clear that no result has been found with a false response.

Up next is a find method, which is similar to get however find returns multiple results, and is set up to be used when working with multiple result sets. Here’s the code:

public function find($where = '', $orderby = '', $limit = '', $start = '', $list = false) {

  	if ( $where ) { $this->db->where($where); }
  	if ( $orderby ) { $this->db->order_by($orderby); }
  	if ( !$start && $limit ) { $this->db->limit($start); }
  	if ( $start && $limit ) { $this->db->limit($start, $limit); }

  	$query  	= $this->db->get($this->_table);

	if ( $query->num_rows() == 0 ) {

		return false;

	} elseif ( $query->num_rows() == 1 && $list == false ) {

		return $query->row_array();

	} else {

		foreach ($query->result_array() as $row) {
			$result[$row['id']]  = $row;
		}

		return $result;

	}

}

This method accepts a number of parameters; where can be an array of where clauses, orderby can be passed in order to set a column to order the results by, limit and start allow you to limit the number of results returned which is especially useful when paging results, and list is a flag used to determine what to return if only a single result is found.

You’ll see four if statements which work out whether to add any whereorderby or limit clauses to the query. Next we fetch the results as before, however this time when we check to see if there are results to return we see if only a single result has been found and if so only return that one. This is where the list flag comes into play, in some situations even if there is only a single result found, you still want it returned as a list of one. You can omit this part if you like but I find it useful when it comes to real world use.

If there’s multiple results found, we construct an array of the results to return. One thing you’ll notice is that we’re setting the return array key to the id of each record. This is useful when solving the n+1 problem, which I’ll cover in a future article.

Finally, we once again return false if there are no records found at all.

Next we will create an insert method, used for creating new records:

public function insert($data) {

	$this->db->insert($this->_table, $data);

	return $this->db->insert_id();

}

This is a much simpler method, that accepts an array of data to insert, and returns the new record’s id. Really easy stuff with Codeigniter’s query builder.

Now for updating, again very easy – here’s the update method:

public function update($data, $value, $field = 'id') {

	$this->db->where($field, $value);
	$this->db->update($this->_table, $data);

	return $id;

}

Similar to the insert method, it accepts an array of fields to update. It also accepts a value and field in a similar manner to the get method above. Most of the time we’ll be updating based on the record’s id so that’s the default, however it allows us to update based on any field in the table.

Finally, we have a delete method:

public function delete($value, $field = 'id') {

	$this->db->where($field, $value);
	$this->db->delete($this->_table);

}

Again, we’re using the same value and field methodology as in the update and get methods above. We’re able to tell it what to delete based on any field/value combination.

Using the Base Model

So, how do we use this thing? Well, here’s some examples.

Say we have a users table on a website where users have their own public profile page and can update all of their details in their account section. We’ll need a model to take care of the database stuff, so let’s create one:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Users_model extends MY_Model {

}

Notice here how we are extending our base model MY_Model, not the CI_Model as you normally would. Doing this gives us access to all the methods above. Yet it still acts as a normal model in Codeigniter because our base model extends CI_Model instead. Think of it like multiple layers of functionality.

There’s one thing left for us to do, our Users_model needs to tell our base model what database table it should use. Easy:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Users_model extends MY_Model {

	protected $_table = 'users';

}

We set the class variable we referenced earlier when setting up our base methods.

Now, in our controllers we can import our Users_model and away we go. Let’s take the public profile page as an example:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Profile extends CI_Controller {

	public function view() {

		$this->load->model('Users_model');

		$data['user_data'] = $this->Users_model->get($this->uri->segment(3), 'slug');

		$this->load->view('profile', $data);

	}

}

Or say a user has submitted a form to update their personal information:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Account extends CI_Controller {

	public function update() {

		$this->load->model('Users_model');

		if ( $this->input->post('submit') ) {

			$update['first_name'] = $this->input->post('first_name');
			$update['last_name'] = $this->input->post('last_name');
			$update['email'] = $this->input->post('email');
			$update['slug'] = $this->input->post('slug');

			$this->Users_model->update($update, $auth->id); // Auth->id would be replaced by however you authorise your members

			redirect('account/update');

		}

		$this->load->view('update');

	}

}

What’s the Point?

You might be looking at the above and wondering “What’s the point?”, especially in cases where the base methods don’t really do much (like delete for example). But remember these are just the bare bones, they could be expanded in your project, or even in future as requirements change – and if they do you now only need to edit a single file. As an example, imagine a situation where you want to log everything that gets deleted in your system, maybe to a flat file or in another table. It might be just for development purposes, but you can add that to a single method in your base model and it will log all deletes for you.

I guess the point is you don’t know what could come up in future, and a little bit of ground work now can save you a whole bunch of time later!