I have users in my Yii app and I use Yii RBAC with CDbAuthManager. In admin panel I have list of users (using zii.widgets.grid.CGridView), which displays their permissions and buttons depends on it (Give/Revoke admin permissions, etc.)

Chunk of view.admin (buttons section):

'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',
    ),
),

My DB log looks like:

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')

So, permissions have been loaded by lazy loading. 100 additional SQL queries for 100 users per page. I can't use 'with', coz AuthAssigment model doen't exist.

The question is: how can I load permissions without one additional SQL query for each single user (using 'with' or somehow else)?

有帮助吗?

解决方案

Ok, there are 2 solutions:

  1. Use CPhpAuthManager instead of CDbAuthManager
  2. Make own class DbAuthManager which extends CDbAuthManager and rewrite some methods to implement logic like in CPhpAuthManager (load items in an array on create, then search this array when checkAccess is called)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top