douchujian8124 2014-12-16 17:21 采纳率: 100%
浏览 41
已采纳

为yii中具有复合的表创建CRUD

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?

  • 写回答

1条回答 默认 最新

  • dt1888 2014-12-17 16:13
    关注

    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!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?
  • ¥100 求三轴之间相互配合画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题