Composite primary key

In another thread it was pointed out to me that I should be using a composite primary key in one of my tables, instead of adding an extraneous column for it. Now I remember why I added the extra column: because the yiic shell crud command doesn’t support composite primary keys.

Anyway, I’m now trying it out. For views and actions I am passing each component of the key as a separate $_GET parameter. So far working fine; is that the way to do it? Is there a simpler alternative?

I’ve done the same in a project to solve this boring and irritating limitation of Yii’s CRUD…the system is working with no issues for about six months, but I still insist that this is a basic ER modeling concept that CRUD should support by default :D

regards!!

Would be nice to have this in yii crud. But I don’t mind doing it manually; would just like to know if there are any tips & tricks, or pitfalls to avoid, when using composite primary keys.

For example, default URLs for buttons in a CButtonColumn will be incorrect.

[In case anyone needs to know how to handle the CButtonColumn issue, here’s one solution:


'columns'=>array(

    array(

        'class'=>'CButtonColumn',

        'viewButtonUrl'=>'Yii::app()->controller->createUrl("view",$data->primaryKey)',

        'updateButtonUrl'=>'Yii::app()->controller->createUrl("update",$data->primaryKey)',

        'deleteButtonUrl'=>'Yii::app()->controller->createUrl("delete",$data->primaryKey)',

    ),

// etc.

Another solution to CGridView button columns for data with a composite primary key:


<?php

/**

 * ButtonColumn class file.

 * ButtonColumn is a simple extension of CButtonColumn.

 * It correctly sets button URLs for data with composite primary keys.

 *

 * @author Jeff Soo

 */


class ButtonColumn extends CButtonColumn

{

    protected function initDefaultButtons()

    {

        $modelClass=$this->grid->dataProvider->modelClass;

        if(is_array($modelClass::model()->primaryKey))

             foreach(array('view','update','delete') as $id)

                $this->{$id.'ButtonUrl'}='Yii::app()->controller->createUrl("'.$id.'",$data->primaryKey)';

        parent::initDefaultButtons();

    }

}

Hi Jsoo,

Where can I find this piece of code? or where should I add this?

Sorry, I’m still confusing.

you said that this will work for composite primary keys right? so does the variable $data->primaryKey stated above return an array containing the composite primary keys? does it return something like: array(‘studentID’=>12, ‘entryYear’=>2011)

I tried that code, and it had a bug. It was lowercasing my model class names, which was completely breaking the UrlManager.

I changed it to this, and it works now.


 		$controller=$modelClass; // do not lowercase the names, it breaks



Hi,

Is the probleme only related to gii crud or will there be a problem with the model ?

I mean, a plan to use a primary composite key for gii model generation, then change the db to a single primary key, generate the crud, then modify sql stucture again to go back to primary composite key.

I suppose i had to modify the controler and view, then it will be ok … i hope …

I’ve had trouble with this too. You can create a full set of views manually though with a table that has a composite primary key. For anyone who encounters this issue, I’ve posted an online yii 1.1.10 crud generator that works for composite keys at http://handsoncoding.net - this will automatically generate a full set of views and a controller based on the gii generated model.