phpkohana-3kohana-orm

Kohana 3.2, calling ORM table models(with has_many relationship) that are put inside a subfolder


I was trying to organize my codes, in application/classes/model/table/ (table directory is just my own created folder), I put all the ORM table models to make it separated from other models.

With that, I also renamed my table models, for example from Model_Applicant >> Model_Table_Applicant then I put a table_name property to match.

Then in my controller, I can call this model by this code,

$applicantModel = ORM::factory('table_applicant');

My problem is, Model_Table_Applicant contains has_many property and I can't iterate the values.(Sorry i cant really put it in words so I will just post my codes).

model/table/applicant.php

class Model_Table_Applicant extends ORM {

    protected $_table_name = 'applicants';

    protected $_has_many = array(
        'table_applicantSkill' => array()
    );
}

model/table/applicantSkill.php

class Model_Table_ApplicantSkill extends ORM {

    protected $_table_name = 'applicant_skills';

}

And in my controller

public function action_testing() {
    $applicantModel = ORM::factory('table_applicant');
    foreach ($applicantModel->find_all() as $applicant) {
        echo $applicant->firstName.'<br>';
        echo '<ul>';
        foreach ($applicant->table_applicantSkill->find_all() as $applicantSkill) {
            echo '<li>'.$applicantSkill->skill.'</li>';
        }
        echo '</ul>';
    }
}

What I am expecting is, it will echo "Alex" then a list of its skills but it just prints "Alex" then an error message

Error Message Unknown column 'table_applicantskill.table_applicant_id' in 'where clause' [ SELECT table_applicantskill...........


Solution

  • As you are working with ORM it would make sense to write your own class that holds the important methods - mainly removing the table_ prefix from values.

    To do so, just create a file APPPATH/classes/ORM.php. The important method here is _initialize(), here the table name, foreign key as well as other values are set.

    Just let Kohana do its thing and remove the prefix if necessary like so

    class ORM extends Kohana_ORM
    {
        protected static function remove_table_prefix($value)
        {
            $pattern = '/^table_(.*)$/i';
            $replace = '\\1';
    
            if (is_string($value))
            {
                return preg_replace($pattern, $replace, $value);
            }
            elseif (is_array($value))
            {
                foreach ($value as &$details)
                {
                    $details['foreign_key'] = self::remove_table_prefix($details['foreign_key']);
                }
                return $value;
            }
            return $value;
        }
    
        protected function _initialize()
        {
            parent::_initialize();
    
            // remove "table_"
            $this->_table_name = self::remove_table_prefix($this->_table_name);
            $this->_belongs_to = self::remove_table_prefix($this->_belongs_to);
            $this->_has_one = self::remove_table_prefix($this->_has_one);
            $this->_has_many = self::remove_table_prefix($this->_has_many);
        }
    }
    

    You might have to modify that a bit further at other points, but locally it worked and you should get the idea.