RSS Feed

Peter Goodman's blog about PHP, Parsing Theory, C++, Functional Programming, Applications,

Active Records in the CodeIgniter Framework

About

I've been working on my own PHP5 framework; however, for work I use the CodeIgniter PHP Framework. For the most part, it's a pretty decent framework. Unfortunately, I think that they've made some mistakes in too. One such mistake is how they handle models and their "active records" system. You can find a detailed account of these on a thread I posted over at the CI forums.

Well, my boss wanted to get rid of all of the redundant SQL queries here and there in site we're working on, so I suggested a new active records system to sit on top of the old one. This system goes into the /application/libraries/ directory of CI but is not accessed as a usual one. Here's how a controller using my ActiveRecords extension looks:

require_once APPPATH .'/libraries/ActiveRecords/controller.php';

class Ar extends ActiveController {
    public function index() {
        // stuff here
    }
}

The only difference--as you will see if you are a CI user--is that the controllers now extend ActiveController instead of the normal Controller. Extending the controller seemed to be the best choice mainly because it allowed me to give the programmer the choice of using the advanced AR system or not without breaking any old code.

Things that need further Testing

So, one of the neat features that I detail in the above linked forum thread is the DatabaseModelDefinition::prepareSelect() function. It allows the programmer to append things to every SQL query created by the finder. While testing the system out yesterday using relations to join one table to another through two intermediate tables, and then joining one of those intermediate tables on to the final table in the prepareSelect, I needed to hack around with database table prefixes. In the relations, tables will be prefixed as so: l, m0, m1 ... mn-1, r (left, middle, right). Well, if you are joining a table in addSelect against one of the original tables in the relation join, then one would expect <table name>.<column> to work. Unfortunately the table needed to be prefixed with what its prefix was in the relation join. So, I made a quick workaround to that (see: SelectQuery::getTablePrefix()). Finally, to get everything to work, you just need to alias any tables you are joining on to the query from the prepareSelect(). From this description, it could be difficult to visualize this problem.

Documentation

I will try to make some nice CodeIgniter-esque documentation for all of this code and how to use it in the near future. :)

Download

You can go grab a ZIP file of this over at http://ioreader.com/code/php/CodeIgniter/ActiveRecords.zip.


Comments


Comment