title: Can I refactor my setup of multiple user types using the same table differently/in a more Cake way?
body: <p>I have a <code>my_users</code> table and I now need to refactor it by deleting the <code>role</code> column in favor of supporting multiple roles per user. So for instance, the 3 user types I'm dealing with are:</p>
  
  <ol>
  <li>fighter</li>
  <li>referee</li>
  <li>manager</li>
  </ol>
  
  <p>So the table setup looks like this:</p>
  
  <p><strong>Users.php</strong></p>
  
  <pre><code>use CakeDC\Users\Model\Table\UsersTable as BaseUsersTable;
  
  class UsersTable extends BaseUsersTable
  {
      public function initialize(array $config)
      {   
          parent::initialize($config);
  
          $this-&gt;setEntityClass('Users\Model\Entity\User');
  
          $this-&gt;belongsToMany('UserRoles', [
              'through' =&gt; 'users_user_roles'
          ]); 
  
          $this-&gt;hasMany('UsersUserRoles', [
              'className' =&gt; 'Users.UsersUserRoles',
              'foreignKey' =&gt; 'user_id',
              'saveStrategy' =&gt; 'replace',
          ]);
      }
  
      public function findRole(Query $query, array $options)
      {
          return $query
              -&gt;innerJoinWith('UserRoles', function($q) use ($options) {
                  return $q-&gt;where(['role_key' =&gt; $options['role_key']]);
              });
      }
  }
  </code></pre>
  
  <p><strong>MyUsersTable.php</strong></p>
  
  <pre><code>class MyUsersTable extends Table
  {   
      public function initialize(array $config)
      {
          parent::initialize($config);
  
          $this-&gt;setTable('my_users');
  
          $this-&gt;setPrimaryKey('user_id');
  
          $this-&gt;belongsTo('Users', [
              'className' =&gt; 'Users.Users',
              'foreignKey' =&gt; 'user_id',
          ]);
      }
  
      /**
       * @param Cake\Event\Event $event
       * @param Cake\ORM\Query $query
       * @param ArrayObject $options
       */
      public function beforeFind(Event $event, Query $query, \ArrayObject $options)
  {
          // set the role
          if (defined(static::class.'::ROLE') &amp;&amp; mb_strlen(static::ROLE) &gt; 0) {
              $role = static::ROLE;
  
              // set user conditions
              $query-&gt;innerJoinWith('Users', function($query) use ($role) {
                  return $query-&gt;find('role', [
                      'role_key' =&gt; $role,
                  ]);
              });
          }
      }
  
      /**
       * @param \Cake\ORM\Query $query
       * @param array $options
       */
      public function findByRegistrationCode(Query $query, array $options): Query
      {
          $query-&gt;where([
              $this-&gt;aliasField('registration_no') =&gt; $options['registration_no']
          ]);
  
          return $query;
      }
  }
  </code></pre>
  
  <p><strong>FightersTable.php</strong></p>
  
  <pre><code>use MyUsers\Model\Table\MyUsers;
  
  class FightersTable extends MyUsersTable
  {       
      const ROLE = 'fighter';
  
      public function initialize(array $config)
      {   
          parent::initialize($config);
  
          $this-&gt;setEntityClass('Fighters\Model\Entity\Fighter');
      }       
  
      /**
       * @param Validator $validator
       * @return Validator $validator
       */
      public function validationDefault(Validator $validator): Validator
      {
          $validator = parent::validationDefault($validator);
  
          $validator-&gt;allowEmpty('field');
      }
  }
  </code></pre>
  
  <p><code>RefereesTable.php</code> and <code>ManagersTable.php</code> are similar to <code>FightersTable</code> but have their own validation rules and may have their own special entity virtual properties and what not.</p>
  
  <p><strong>Question:</strong> Is there a more cake way of structuring this, or more specifically an alternate way to doing the <code>beforeFind</code> to distinguish the role? Had the requirement for <code>role</code> stayed 1:1 with users, I might have possibly done something like this:</p>
  
  <pre><code>$this-&gt;belongsTo('Fighters', [
      'conditions' =&gt; [
          'role' =&gt; 'fighter'
      ],
      'foreignKey' =&gt; 'user_id',
      'className' =&gt; 'MyUsers',
  ]);
  </code></pre>
  
  <p>I'd appreciate any insight into restructuring this.</p>