So i have a many to many relation between two tables which are "Item" and "Tier" and i have an intermediate table "Item_Tier" which both of there Fks acting as Pks which will make the key a composite key.
Now i am trying to make a simple CRUD for the intermediate table and i know that Yii has a limitation that it cant create the CRUD for tables with composite keys. I have fond the extension Giix which advertises that it does support the CRUD for composite keys.
Now i have followed it installation process and I can see that it is added to my Gii because I can see the Giix crud and model generator. I have create the model with both Giix and gii to make sure it has no effect and it still gives me the error that it can not create the CRUD because of the Composite id.
How can i fix this please?
I think that you may not need CRUD operations for many_many connection tables.
You have the Item and Tier CActiveRecords for the two tables.
You can specify these relations in them:
// Item
public function relations(){
return array(
...
'tiers'=>array(self::MANY_MANY,'Tier', 'Item_Tier(item_id, tier_id)'),
...
);
}
// Tier
public function relations(){
return array(
...
'items'=>array(self::MANY_MANY,'Item', 'Item_Tier(tier_id, item_id)'),
...
);
}
So now you can read the items for a tier, and the tiers for an item. Then you can create an addItem($item) function in the Tier class (or an addTier($tier) in the item class, similar to this)
Add connection:
// Tier class
public function addItem(Item $item){
// check if item is saved. You may check if the current tier object is saved, similarly if($this->isNewRecord){...}
if($item->isNewRecord){
// item object is not saved into the db yet, cannot assign
// you can try to save it here, or throw an exception, or just return false and handle where you call this method
return false;
}
$exists = Yii::app()->db->createCommand
->from('Item_Tier')
->where('item_id=:iid AND tier_id=:tid',array(':iid'=>$item->id,':tid'=>$this->id))
->queryRow();
if($exists !== FALSE){
// this item is already added to this tier
return true;
}
$affectedRows = Yii::app()->db->createCommand->insert('Item_Tier',array('item_id'=>$item->id,'tier_id'=>$this->id));
return $affectedRows > 0;
}
Now you can also assign items to tiers, and tiers to items (if you implement a similary method in the Item class)
Delete connection:
// Tier class
public function deleteItem(Item $item){
// check if item is saved. You may check if the current tier object is saved, similarly if($this->isNewRecord){...}
if($item->isNewRecord){
// item object is not saved into the db yet, cannot assign
// you can try to save it here, or throw an exception, or just return false and handle where you call this method
return false;
}
$affectedRows = Yii::app()->db->createCommand->delete('Item_Tier','item_id=:iid AND tier_id=:tid',array(':iid'=>$item->id,':tid'=>$this->id));
return $affectedRows > 0;
}
And an update is equivalent of deleting a connection and adding a new connection. This way you don't have to create a new AR class for the connection table with crud operations.
Hope this helps!