Domanda

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

È stato utile?

Soluzione

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)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top