1
votes

I just started my project with cakephp3.0. I startet with the Users. I put a function isAuthorized in the UsersController which should validate if the User is permitted to view other users, to edit other users and so on.

I created a table "userprivileges" where all possible privileges, which can be assigned to a user are listed. The table is "userprivileges" is:

id | controller | function

Next I want to group the priviliges into roles. I created following table: "userprivilegeroles"

id | role 

Next I created the BTM-Table: "userprivileges_userprivilegeroles"

id | userprivilegerole_id | userprivilegerole_id

The User is linked to the userprivilegeroles table, so I need to search if the requested controller/function is view-able for the user.

I tried like this:

$this->loadModel('Userprivilegeroles');
$userprivilegeroles = $this->Userprivilegeroles->find('all', [
    'conditions' => [
        'Userprivileges.controller' => $this->request->controller,
        'Userprivileges.function' => $this->request->action], 
    'contain' => ['Userprivileges']
]);

Now this fails with following error:

Userprivilegeroles is not associated with Userprivileges.

There is a little more description, where I can search for the problem prompted to the 500 page.

  • The class for the specified table does not exist.
  • The Table was created with a typo: TableRegistry::get('Atricles');
  • The class file has a typo in the name or incorrect namespace: class Atricles extends Table
  • The file containing the class has a typo or incorrect casing: Atricles.php
  • The Table was used using associations but the association has a typo: $this->belongsTo('Atricles')
  • The table class resides in a Plugin but no plugin notation was used in the association definition.

Lets go for it one by one:

The class for the specified table does not exist.

It does:

namespace App\Model\Table;

use Cake\ORM\Table;
use Cake\Validation\Validator;

class UserprivilegerolesTable extends Table
{
    public function initialize(array $config){
        $this->belongsToMany('Userprivileges', [
            'joinTable' => 'userprivileges_userprivilegeroles',
            'className' => 'Userprivileges'
        ]);
    }       
}

Next

The Table was created with a typo: TableRegistry::get('Atricles');

No.

The class file has a typo in the name or incorrect namespace: class Atricles extends Table

no.

The file containing the class has a typo or incorrect casing: Atricles.php

no. its in src/Model/Table/Userprivilegeroles.php

The Table was used using associations but the association has a typo: $this->belongsTo('Atricles')

See above. I don't see a typo.

The table class resides in a Plugin but no plugin notation was used in the association definition.

As described, I called it from the UsersController.

Can anyone help me finding, why the association doesn't work as expected? Maybe I am to much stuck in the cakephp 2.0 ORM, but I am almost sure that I did the association like described in the cookbook.

I've searched already and found some other issues with the belongstomany association. But they all handle problems with saving data. I want to search data, so I see no connection there.

1
Unrelated to the problem you're having, I think you might save yourself a lot of typing, without really losing any useful specificity, if you called the tables simply "privileges" and "roles" and "privileges_roles".Greg Schmidt
Thank you for your hint. Actually, I knowingly decided to do so, because priviliges and roles will be used in another context again. So I needed to seperate beetween the user-related context and other parts of the App.Andreas Witte

1 Answers

1
votes

Actually the filename is incorrect, filenames must match classnames (PSR-4), so it should be UserprivilegerolesTable.php. The warning notes may need some fixing or further explanation, as they are a little misleading by not using the Table suffix.

Once you've fixed that you'll stumble over the next problem, contained belongsToMany and hasMany associations cannot be used in conditions, as they are retrieved in a separate query, you'll have to use matching() instead.