Extending CodeIgniter’s Active Record Class

If you’re here you’ve probably realized by now that CodeIgniter 2.0 doesn’t officially support extending the core Active Record class, which is a bit of a drag.

As you may know, CI 2.0 came with a new core/ folder that allows you to simply drop classes to extend the CI core with.

For example, to extend the base CI_Loader class, you would just drop in MY_Loader.php into the /application/core folder, and all is set and done. Of course, you’d make sure that the ‘subclass_prefix’ config variable is set to ‘MY_’. This is the default configuration.

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

Being able to just drop in subclasses in the core/ folder is pure awesome, because you don’t need to modify the core CI classes to extend its functionality, and you keep everything separate in each /application instance.

You may think you can just drop in a file called “MY_DB_active_rec.php” into the /application/core folder, but this is not the case. It will not work, as verified by Phil Sturgeon himself in this StackOverflow post.

To do so requires a teeny bit of hacking of the core CI files. If you don’t like the idea of doing so, you may want to just head home now.

Still with me? The good news is that this only requires a few lines of code change. Here we go:

Locate the piece of code in

/system/database/DB.php

, starting on line 110 (as of CI 2.0.0):

require_once(BASEPATH.'database/DB_driver'.EXT);

if ( ! isset($active_record) OR $active_record == TRUE)
{
    require_once(BASEPATH.'database/DB_active_rec'.EXT);

    if ( ! class_exists('CI_DB'))
    {
        eval('class CI_DB extends CI_DB_active_record { }');
    }
}

This is the bit of code that loads CI’s active record class. Replace it with this:

require_once(BASEPATH.'database/DB_driver'.EXT);

if ( ! isset($active_record) OR $active_record == TRUE)
{
    require_once(BASEPATH.'database/DB_active_rec'.EXT);
   
    // get the CI instance
    $CI = & get_instance();
    $prefix = $CI->config->item('subclass_prefix');
   
    if (file_exists(APPPATH.'core/'.$prefix.'DB_active_rec'.EXT))
    {
        require_once(APPPATH.'core/'.$prefix.'DB_active_rec'.EXT);
        if ( ! class_exists('CI_DB'))
        {
            eval('class CI_DB extends '.$prefix.'DB_active_record { }');
        }
    }
    else
    {
        if ( ! class_exists('CI_DB'))
        {
            eval('class CI_DB extends CI_DB_active_record { }');
        }
    }
}

What happens here is that it will check the /application/core/ folder to see if a “MY_DB_active_rec.php” file exists (where MY_ is the prefix name you specified in your config file), and if it does, it loads that instead of the CI_DB_active_record class.

Next you’ll also need to extend the CI_Loader class to override the database() method, as well as the specific database driver that you’ll be using. In my case I extended the CI_DB_mysql_driver to override the _insert() method to allow the “INSERT DELAYED” feature of MySQL.

I’ve included a zip file of the changes. The files below were meant for CodeIgniter 2.0.0. CI 2.0.1+ shouldn’t be much more different, just get into the file and look around to make the necessary adjustments.

Download extend_ci_active_record.zip

This entry was posted in Uncategorized. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

One Comment

  1. Posted October 11, 2011 at 6:18 pm | Permalink

    There is a way to extend the active record class methods without changing the system files. follow this guide:

    http://www.simonemms.com/code/extending-the-codeigniter-database-class/

    and put all your overriding methods in MY_DB_mysql_driver.php

2 Trackbacks

  1. [...] need to do same thing over and over again when you upgrade your CI. Have a look at this article or this one (or search google) if you want to do so [...]

  2. [...] and doesn’t last across framework updates.However, thanks to the articles I found here and here, I came up with my own solution.This extension requires 1) a custom Loader class, 2) a custom DB [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>