2015-12-22 4 views
0

J'essaie de créer un ensemble de CRUD en utilisant cakephp3. Mon modèle de base de données ressemble à ceci:Comment puis-je relier correctement ces tables dans cakephp?

My ER model

J'ai utilisé le tutoriel de gâteau sur l'authentification pour créer la table des utilisateurs et ses classes, il fonctionne très bien. Mais je veux utiliser un ensemble de rôles plus complexe, j'ai donc créé ces autres tables. Après avoir créé le modèle de base de données, j'ai cuit les classes correspondantes, j'ai fait quelques ajustements et j'ai fait fonctionner les systèmes et les rôles CRUD. Maintenant, je veux intégrer la table roles_users, probablement à l'intérieur du CRUD de l'utilisateur.

Je voudrais voir comment cake cakes le ferait avant de coder cette relation moi-même, mais je suis incapable d'ouvrir/rolesUsers. Quand j'appelle l'URL, je reçois le message d'erreur suivant:

Cannot match provided foreignKey for "Roles", got "(role_id)" but expected foreign key for "(id, system_id)" RuntimeException 

Je pense que cela se produit parce que system_id est un PK dans le tableau des rôles et ne sont pas présents dans roles_users (je vais vous montrer les modèles cuits au four et ce PK sera présent à la classe des rôles). Existe-t-il un moyen facile de le faire fonctionner sans ajouter system_id dans roles_users? IMO ajoutant ce champ supplémentaire ne serait pas un gros problème, mais je voudrais savoir si je fais quelque chose de mal, une mauvaise décision de conception.

Mon src/Modèle/Table/RolesUsersTable.php:

<?php 
namespace App\Model\Table; 

use App\Model\Entity\RolesUser; 
use Cake\ORM\Query; 
use Cake\ORM\RulesChecker; 
use Cake\ORM\Table; 
use Cake\Validation\Validator; 

/** 
* RolesUsers Model 
* 
* @property \Cake\ORM\Association\BelongsTo $Users 
* @property \Cake\ORM\Association\BelongsTo $Roles 
*/ 
class RolesUsersTable extends Table 
{ 

    /** 
    * Initialize method 
    * 
    * @param array $config The configuration for the Table. 
    * @return void 
    */ 
    public function initialize(array $config) 
    { 
     parent::initialize($config); 

     $this->table('roles_users'); 
     $this->displayField('user_id'); 
     $this->primaryKey(['user_id', 'role_id']); 

     $this->belongsTo('Users', [ 
      'foreignKey' => 'user_id', 
      'joinType' => 'INNER' 
     ]); 
     $this->belongsTo('Roles', [ 
      'foreignKey' => 'role_id', 
      'joinType' => 'INNER' 
     ]); 
    } 

    /** 
    * Default validation rules. 
    * 
    * @param \Cake\Validation\Validator $validator Validator instance. 
    * @return \Cake\Validation\Validator 
    */ 
    public function validationDefault(Validator $validator) 
    { 
     $validator 
      ->add('valido_ate', 'valid', ['rule' => 'date']) 
      ->requirePresence('valido_ate', 'create') 
      ->notEmpty('valido_ate'); 

     return $validator; 
    } 

    /** 
    * Returns a rules checker object that will be used for validating 
    * application integrity. 
    * 
    * @param \Cake\ORM\RulesChecker $rules The rules object to be modified. 
    * @return \Cake\ORM\RulesChecker 
    */ 
    public function buildRules(RulesChecker $rules) 
    { 
     $rules->add($rules->existsIn(['user_id'], 'Users')); 
     $rules->add($rules->existsIn(['role_id'], 'Roles')); 
     return $rules; 
    } 
} 

Mon src/Modèle/Table/RolesTable.php:

<?php 
namespace App\Model\Table; 

use App\Model\Entity\Role; 
use Cake\ORM\Query; 
use Cake\ORM\RulesChecker; 
use Cake\ORM\Table; 
use Cake\Validation\Validator; 

/** 
* Roles Model 
* 
* @property \Cake\ORM\Association\BelongsTo $Systems 
*/ 
class RolesTable extends Table 
{ 

    /** 
    * Initialize method 
    * 
    * @param array $config The configuration for the Table. 
    * @return void 
    */ 
    public function initialize(array $config) 
    { 
     parent::initialize($config); 

     $this->table('roles'); 
     $this->displayField('name'); 
     $this->primaryKey(['id', 'system_id']); 

     $this->belongsTo('Systems', [ 
      'foreignKey' => 'system_id', 
      'joinType' => 'INNER' 
     ]); 
    } 

    /** 
    * Default validation rules. 
    * 
    * @param \Cake\Validation\Validator $validator Validator instance. 
    * @return \Cake\Validation\Validator 
    */ 
    public function validationDefault(Validator $validator) 
    { 
     $validator 
      ->add('id', 'valid', ['rule' => 'numeric']) 
      ->allowEmpty('id', 'create'); 

     $validator 
      ->requirePresence('name', 'create') 
      ->notEmpty('name'); 

     $validator 
      ->add('status', 'valid', ['rule' => 'numeric']) 
      ->requirePresence('status', 'create') 
      ->notEmpty('status'); 

     return $validator; 
    } 

    /** 
    * Returns a rules checker object that will be used for validating 
    * application integrity. 
    * 
    * @param \Cake\ORM\RulesChecker $rules The rules object to be modified. 
    * @return \Cake\ORM\RulesChecker 
    */ 
    public function buildRules(RulesChecker $rules) 
    { 
     $rules->add($rules->existsIn(['system_id'], 'Systems')); 
     return $rules; 
    } 
} 

Mon src/Modèle/Table/UsersTable:

<?php 
namespace App\Model\Table; 

use Cake\ORM\Table; 
use Cake\Validation\Validator; 
class UsersTable extends Table{ 
    public function validationDefault(Validator $validator){ 
     return $validator 
      ->notEmpty('username', 'O campo nome de usuário é obrigatório') 
      ->notEmpty('password', 'O campo senha é obrigatório') 
      ->notEmpty('role', 'O campo perfil é obrigatório') 
      ->add('role', 'inList', [ 
       'rule' => ['inList', ['admin', 'author']], 
       'message' => 'Escolha um perfil válido' 
       ] 
      ); 

    } 
} 
?> 

Répondre

3

une réponse en jose_zap utilisateur dans @freenode # cakephp:

Dans RolesUsersTable.php, initialisez la fonction, j'ai ajouté un paramètre aux appels $ this-> belongsTo, y compris le 'bindingKey' et la valeur 'id'. Donc, ce vieux code:

$this->belongsTo('Users', [ 
     'foreignKey' => 'user_id', 
     'joinType' => 'INNER' 
    ]); 
    $this->belongsTo('Roles', [ 
     'foreignKey' => 'role_id', 
     'joinType' => 'INNER' 
    ]); 

est devenu ceci:

$this->belongsTo('Users', [ 
     'foreignKey' => 'user_id', 
     'bindingKey' => 'id', 
     'joinType' => 'INNER' 
    ]); 
    $this->belongsTo('Roles', [ 
     'foreignKey' => 'role_id', 
     'bindingKey' => 'id', 
     'joinType' => 'INNER' 
    ]);