belongs_to on non primary_key


I am trying to use a belongs_to relation but i want the join to be on a field of the other table which is not its primary key.

For instance:

Students table:




Grade table



return array(

			'student' => array(self::BELONGS_TO,'Student','student_reference)


with this code the grade model will do a join on the id of the student table because that is its primary key. but for me that’s not the goal.

thanks for your help.

Please check the additional options of the relations tutorial:

Thanks Antonio but I read that before and I didn’t find any option which affect this. I also tried to set the primaryKey on the related model to the reference but that didn’t helped. I assume the yii first checks if there is a primarykey defined and it just calls the primayKey method when it doesn’t. I think I need a workaround here.

You can set a custom primaryKey you know that right? Nevertheless, I wonder why would you reference your table Grade to a student’s reference instead of its ID. Relations should be obscure to the view, any specific reason to do it that way?


edit: I said that because through proper relationship you can from Grade get the student reference by lazy loading or eager loading approach and same from Student model.

for some reason, it haven’t worked for me, but possibly it was my bad. and since I didn’t have much time to stuck with this problem I made a workaround.

the reason is the usual. needs to work with an old database which used by other applications as well so changes are not possible with the database structure and the data is connected throught an non primary key field(the grade_id was just an example)

i know this. the problem was that a whole bunch of data could come from a place where the primary key of the first table is not available just if I make an sql lookup. I was trying to avoid that so that’s why I tried to make the connection on the non primary key field.

anyway thanks for your thoughts on it. when I got some time I will try to figure out why it didn’t want to set the primarykey in the model.

I found at the forum, people had problems with the string base foreign-keys. Maybe that is your case too. I looked around for composite primary keys and it seems a very discussed subject.

Maybe you can mimic a lazy loading approach here… Try this and let me know if it works for you. Create a property on Grade like this:

private $_student = false; //<-- will hold a reference to the student

public function getStudent(){

    // we do not check against null as CActiveRecord.find() method

    // returns null if none is found

    if( false === $_student ) 

        $this->_student = Student::model()->find('reference="'.$this->student_reference.'"');

    return $this->_student;


I know it is not the perfect solution but for that database design, maybe this is a solution for you.


If somebody will find this when looking for solution (=

How to use another primary key:

// who_add is property of Person

// user_id is property of MCompany

// We use user_id instead id

class Person extends BasePerson


  public function relations()


    return array(

      'company' => array(self::BELONGS_TO, 'MCompany', array('who_add'=>'user_id')),