2014-03-28 24 views
0

我的Yii應用程序中有用戶,我使用Yii RBAC和CDbAuthManager。 在管理面板我有用戶列表(使用zii.widgets.grid.CGridView),它顯示他們的權限和按鈕取決於它(給/撤銷管理員權限等)Yii ActiveRecord和AuthAssigment表

塊的view.admin(按鈕部分):

'setAdmin'=>array(
    'label'=>'<span class="glyphicon glyphicon-tower"></span>', 
    'imageUrl' => false, 
    'url'=>'Yii::app()->controller->createUrl("setAdmin",array("id"=>$data->primaryKey))', 
    'visible'=>'(! Yii::app()->getAuthManager()->checkAccess("admin", $data->primaryKey)) && ($data->is_blocked == 0) && ($data->is_verified != 0)', 
    'options'=>array(
     'class'=>'btn btn-warning btn-xs', 
     'title'=>'Give administrator permissions', 
    ), 
), 
'unsetAdmin'=>array(
    'label'=>'<span class="glyphicon glyphicon-user"></span>', 
    'imageUrl' => false, 
    'url'=>'Yii::app()->controller->createUrl("unsetAdmin",array("id"=>$data->primaryKey))', 
    'visible'=>'(Yii::app()->getAuthManager()->checkAccess("admin", $data->primaryKey)) && ($data->primaryKey != Yii::app()->user->id)', 
    'options'=>array(
     'class'=>'btn btn-primary btn-xs', 
     'title'=>'Revoke administrator permissions', 
    ), 
), 

我的DB日誌是這樣的:

system.db.CDbCommand.query(SELECT * FROM `AuthAssignment` WHERE userid=:userid. Bound with :userid='189') 
system.db.CDbCommand.query(SELECT * FROM `AuthAssignment` WHERE userid=:userid. Bound with :userid='106') 
system.db.CDbCommand.query(SELECT * FROM `AuthAssignment` WHERE userid=:userid. Bound with :userid='351') 
system.db.CDbCommand.query(SELECT * FROM `AuthAssignment` WHERE userid=:userid. Bound with :userid='138') 
system.db.CDbCommand.query(SELECT * FROM `AuthAssignment` WHERE userid=:userid. Bound with :userid='46') 
system.db.CDbCommand.query(SELECT * FROM `AuthAssignment` WHERE userid=:userid. Bound with :userid='186') 
system.db.CDbCommand.query(SELECT * FROM `AuthAssignment` WHERE userid=:userid. Bound with :userid='306') 
system.db.CDbCommand.query(SELECT * FROM `AuthAssignment` WHERE userid=:userid. Bound with :userid='174') 
system.db.CDbCommand.query(SELECT * FROM `AuthAssignment` WHERE userid=:userid. Bound with :userid='71') 
system.db.CDbCommand.query(SELECT * FROM `AuthAssignment` WHERE userid=:userid. Bound with :userid='281') 
system.db.CDbCommand.query(SELECT * FROM `AuthAssignment` WHERE userid=:userid. Bound with :userid='173') 
system.db.CDbCommand.query(SELECT * FROM `AuthAssignment` WHERE userid=:userid. Bound with :userid='290') 
system.db.CDbCommand.query(SELECT * FROM `AuthAssignment` WHERE userid=:userid. Bound with :userid='171') 
system.db.CDbCommand.query(SELECT * FROM `AuthAssignment` WHERE userid=:userid. Bound with :userid='83') 

因此,權限已被延遲加載加載。 100個額外的SQL查詢,每頁100個用戶。 我不能使用'with',因爲AuthAssigment模型不存在。

問題是:如何爲每個單個用戶(使用'with'或其他方式)加載沒有額外SQL查詢的權限?

+0

這個問題比我猜得更加深入。 [checkAccess](http://www.yiiframework.com/doc/api/1.1/CDbAuthManager#checkAccess-detail)調用[checkAccessRecursive](http://www.yiiframework.com/doc/api/1.1/CDbAuthManager# checkAccessRecursive-detail),它使用'$ this-> getAuthItem($ itemName)'。而且這個方法([getAuthItem](http://www.yiiframework.com/doc/api/1.1/CDbAuthManager#getAuthItem-detail))會執行額外的查詢 – Kirill

回答

0

好了,有2個解決方案:

  1. 使用CPhpAuthManager而不是CDbAuthManager
  2. 使延伸CDbAuthManager自己的類DbAuthManager和重寫在創建陣列的一些方法CPhpAuthManager實現類似的邏輯(加載項,然後搜索這個數組時的checkAccess被調用)