문제

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