Welcome Guest, Not a member yet? Register   Sign In
ActiveRecord library - one to one solution proposal
#1

[eluser]esbium[/eluser]
Coming from a Java world where we have things like Hibernate for ORM, I have taken the persistence layer for granted for a while now. I recently started developing a php app on CI and found the ActiveRecord library in the Wiki. Its great and its probably only going to get better. One thing I found that I don't like though is that it only supports 1-1 relationships with a pivot table.

I developed an extension to that library to handle normalized 1-1 relationships and thought I would post it here to get feedback, ideas, etc. This is just the start of it and I have only tested it with a few relationships. They seem to work though.

Keep in mind while reading this post that I have been a Java developer for years but just recently started working with PHP professionally. It has been a hobby for a few years though. If you see mistakes in my code, please don't hesitate to point them out!

Enough chatter! Here is the __call function in the ActiveRecordEnhanced class:

Code:
public function __call($method, $args)
{
    if(stristr($method, 'fetch_1to1_')) return    $this->_fetch_one_to_one(str_replace('fetch_1to1_', '', $method), $args);
    //if not one of our new methods, call the original
    return parent::__call($method, $args);
}

And here is the private _fetch_one_to_one function:
Code:
private function _fetch_one_to_one($oneToOneTable, $args)
{
        //TODO this will break for person/people etc..  Find a way to load the other model and get its _table attribute, maybe...
        $relationshipTable = $oneToOneTable . 's';    
        
        $query = $this->db->query('
            SELECT
                ' . $relationshipTable . '.*
            FROM
                ' . $relationshipTable . '            
            WHERE
                ' . $relationshipTable . '.id = ' . eval('return $this->' . $oneToOneTable . '_id;')
        );        
        eval('$this->' . $oneToOneTable . ' = $query->row();');    
        //TODO, what do we do if it returns no results?
        if(empty($this->$oneToOneTable))
            $this->$oneToOneTable = new stdClass();
}

So, given a data relationship like Task -> Project, meaning each Task has a parent Project, and the Task table has a column like 'project_id', I can now write code like this:
Code:
$task = $this->load->model('task');
$tasks = $this->task->find(ALL);
foreach($tasks as $tsk)
{
    echo "Task name = " . $tsk->name . '<br/>';
    //load the parent project
    $tsk->fetch_1to1_project();
    echo 'Parent Project name: ' . $tsk->project->name;
}

What does the CI community think? Am I on the right track? Also, am I duplicating efforts? I don't want to use ORM solutions like Propel or Doctrine, I have my reasons.

Let me know!!


Messages In This Thread
ActiveRecord library - one to one solution proposal - by El Forum - 09-28-2007, 05:50 PM
ActiveRecord library - one to one solution proposal - by El Forum - 09-29-2007, 04:09 PM
ActiveRecord library - one to one solution proposal - by El Forum - 09-29-2007, 04:58 PM
ActiveRecord library - one to one solution proposal - by El Forum - 09-29-2007, 05:14 PM
ActiveRecord library - one to one solution proposal - by El Forum - 09-30-2007, 12:43 AM
ActiveRecord library - one to one solution proposal - by El Forum - 09-30-2007, 06:46 AM
ActiveRecord library - one to one solution proposal - by El Forum - 09-30-2007, 10:23 AM
ActiveRecord library - one to one solution proposal - by El Forum - 09-30-2007, 12:03 PM



Theme © iAndrew 2016 - Forum software by © MyBB