Setting a primary key in CActiveRecord

Hi All,

I am working with an old MSSQL database that was designed years ago, as such is not set up in the best way possible. To get the relations working in my model I need to set the primary key of each model. How do I do that?

I notice the getPrimaryKey() and setPrimaryKey() methods of the class but not sure what to return or how to use them?

Now sure about MSSQL, Buy Yii will automatically populate the primarykey by the table metaData. If you want to explicitly setting the primary key you can do that by simple defining the property primaryKey:

http://www.yiiframework.com/doc/api/CActiveRecord#primaryKey-detail

Hi Vince, still can’t get it working…

for example…




class Tenant extends CActiveRecord

{

	var	$primaryKey = 'house_ref';

	

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}

	

	

	public function getDbConnection()

	{

		return Yii::app()->uhtest;

	}

	

	public function tableName()

	{

		return 'dbo.househ';

	}

	

	

	public function relations()

	{

		return array(

			'tenancies' => array(self::HAS_MANY, 'Tenancies', 'house_ref')

		);

	}

}







class Tenancies extends CActiveRecord

{

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}

	

	

	public function getDbConnection()

	{

		return Yii::app()->uhtest;

	}

	

	public function tableName()

	{

		return 'dbo.tenagree';

	}

	

	public function relations()

	{

		return array(

			'tenant' => array(self::BELONGS_TO, 'Tenant', 'house_ref')		 

		);

	}

}



Lazy loading the relation causes an error…




PHP Error

Description


Invalid argument supplied for foreach()

Source File


/var/frameworks/yii-1.1.1/framework/db/ar/CActiveFinder.php(442)


...



Well, First thing first, You should use one of the visibility statements such as public/protected/private when defining class members, var is deprecated.

Second, You should include the entire error and callstack. Since the error you’ve displayed is very general.

Third, Try overriding the setPrimarKey method. I also assume that Yii resolves the primaryKey by accessing http://www.yiiframework.com/doc/api/CDbTableSchema#primaryKey

Fixed the member declaration to public and still receive the error. Here’s the entire trace…




PHP Error

Description


Invalid argument supplied for foreach()

Source File


/var/frameworks/yii-1.1.1/framework/db/ar/CActiveFinder.php(442)


00430: 

00431:     /**

00432:      * Performs lazy find with the specified base record.

00433:      * @param CActiveRecord the active record whose related object is to be fetched.

00434:      */

00435:     public function lazyFind($baseRecord)

00436:     {

00437:         if(is_string($this->_table->primaryKey))

00438:             $this->records[$baseRecord->{$this->_table->primaryKey}]=$baseRecord;

00439:         else

00440:         {

00441:             $pk=array();

00442: foreach($this->_table->primaryKey as $name)

00443:                 $pk[$name]=$baseRecord->$name;

00444:             $this->records[serialize($pk)]=$baseRecord;

00445:         }

00446: 

00447:         foreach($this->stats as $stat)

00448:             $stat->query();

00449: 

00450:         if(empty($this->children))

00451:             return;

00452: 

00453:         $child=reset($this->children);

00454:         $query=new CJoinQuery($child);


Stack Trace


#0 /var/frameworks/yii-1.1.1/framework/db/ar/CActiveFinder.php(214): CJoinElement->lazyFind()

#1 /var/frameworks/yii-1.1.1/framework/db/ar/CActiveRecord.php(237): CActiveFinder->lazyFind()

#2 /var/frameworks/yii-1.1.1/framework/db/ar/CActiveRecord.php(105): Tenant->getRelated()

#3 /var/www/vhosts/my.charterhousing.co.uk/protected/controllers/SiteController.php(21): Tenant->__get()

#4 /var/frameworks/yii-1.1.1/framework/web/actions/CInlineAction.php(32): SiteController->actionIndex()

#5 /var/frameworks/yii-1.1.1/framework/web/CController.php(300): CInlineAction->run()

#6 /var/frameworks/yii-1.1.1/framework/web/CController.php(278): SiteController->runAction()

#7 /var/frameworks/yii-1.1.1/framework/web/CController.php(257): SiteController->runActionWithFilters()

#8 /var/frameworks/yii-1.1.1/framework/web/CWebApplication.php(320): SiteController->run()

#9 /var/frameworks/yii-1.1.1/framework/web/CWebApplication.php(120): CWebApplication->runController()

#10 /var/frameworks/yii-1.1.1/framework/base/CApplication.php(135): CWebApplication->processRequest()

#11 /var/www/vhosts/my.charterhousing.co.uk/index.php(12): CWebApplication->run()




I have also tried putting the setPrimaryKey() method in the model and still retrieve the same error…




public function setPrimaryKey()

	{

		return 'house_ref';

	}



Not sure, But try setting the primary key as follows:




public $primaryKey = array( 'house_ref' );



Unfortunately it’s the same error…

As an update I have fixed this issue now. It turns out the database I was using had been designed poorly and had no primary keys assigned. I therefore needed to tell Yii what the primary keys were as Yii kept returning them as NULL forcing AR to fail. I found the answer in the guide: http://www.yiiframework.com/doc/guide/database.ar where in order to tell it the primary key I placed the primaryKey() method in the AR model. This had to be done in all other models for AR to work properly.

Everything is working great now.

I am continually pleased by how intelligent I am find Yii. Great work from all the development team.