Is there a way to use filtering (searching) in CGridView for a model attribute which is not a DB column?
I have a User model which has a role attached to it (using Yii RBAC). In the manage users page I use CGridView to display all users and I also display each user’s role. I want to be able to search also by role but I don’t want to use a model relation between User and AuthItem because I would like to keep my RBAC code independent of the actual RBAC implementation that I use. I may switch to CPhpAuthManager or another (LDAP for example) at a later stage. I would like to stick to CAuthManager API for accessing and managing RBAC specific functions.
So is there a way to make CGridView search/filter a model attribute which is not DB-backed, i.e. continue to use the CActiveDataProvider for the normal model attributes and different provider (that is using CAuthManager for reading the roles) for the role field?
I can’t see any way that you would be able to sort or filter in CGridView using a non db attribute - the filtering/sorting is done using SQL generated from the model, so will only work on values that can be used in the SQL.
Depending on how you’re creating your CActiveDataProvider for use with the grid view, then you could perhaps do getData() on it, to retrieve the data, then manually sort it before passing it to the grid view, but obviously any such sorting and filtering would then only be applied to the current grid page.
well, I think it’s not impossible. but before that, how are you populating users’ roles in gridView now? you set their roles in their session or what?
and another question could be how many roles a user can have?
assuming each user has one role (just for simplicity, main idea would be the same) if I had this problem, I would use CArrayDataProvider instead of CActiveDataProvider. this way we can simply load our data from DB using Active Record and user Model, then we can filter it using whatever function we want, and finally, we can populate our ArrayDataProvider and pass it to view.
so our search function would be something like this: (pseudo code, of course)
$criteria = new CDbCriteria;
$criteria->condition = filtering normal db parameters
$rawResults = self::model()->findAll($criteria);
$usefulRawResults = self::attachRoles($rawResults); // you probably will attach each users role to its AR object so we can refer later, lets say using this function
$finalResults = self::filterByRole($specificRole, $usefulRawResults); // this function can simply loop users and check if one has this role or not, returning the ones pass the if
$arrayDataProvider = new CArrayDataProvider;
$arrayDataProvider <= we should make $finalResults ready and pass it to arrayDataProvider, documentations will help a lot
I think that’s the whole Idea, see if it works, and if there were any problems, let me know