php - How to query another table inside a BuildRules() Function - CakePHP 4.x

I am trying to query a different table inside my SRC/Model/Table/InspectorsTable.php file within the buildRules() function.

Background info:

  • Currently, my system uses a User table to store login information. HERE is the model.

  • This Users table has 3 different profile tables associated with it. Inspectors, Contractors, and Employees.

  • As of now, an Inspector, Contractor, and Employee record can use the same User foreign key to login.

  • I am trying to make it so that a single User record, can only use a single record from either Inspector OR Contractor OR Employee to login.

  • E.g. 1 User Record for 1 Employee Record/Inspector Record/Contractor Record.

I was thinking to do that, I could use the buildRules() function to check the other tables to see if the primary key of Users table is already being used by another table on the creation of an Inspector, Contractor, or Employee. If it is, it will not create the record.

My Attempt:

To try and implement the above logic, I have tried to query one of my other tables (as seen below). However, this is not working.

Here is the SRC/Model/Table/InspectorTables.php:

class InspectorsTable extends Table
{
    public function initialize(array $config): void
    {
        parent::initialize($config);

        $this->setTable('inspectors');
        $this->setDisplayField('id');
        $this->setPrimaryKey('id');

        $this->belongsTo('Users', [
            'foreignKey' => 'user_id',
            'joinType' => 'INNER',
        ]);
    }
    
    public function buildRules(RulesChecker $rules): RulesChecker
    {
        $rules->add($rules->existsIn(['user_id'], 'Users'), ['errorField' => 'user_id']);

        // this line does not work
        print_r($this->Contractor->get(10000000));

        return $rules;
    }
}

However, I am getting this error when I try to do this:

Undefined property Contractor. You have not defined the Contractor association on App\Model\Table\InspectorsTable

I believe this is occurring because of the association's setup in the initialize() function of the InspectorsTable.php

Any help/alternative solutions would be great! Thank you!

Answer

Solution:

There is no association between Inspectors and Contractors, hence there's no magic association property that you could access on your InspectorsTable class.

To access "unrelated" tables, use the table locator, for example via the LocatorAwareTrait:

class InspectorsTable extends Table
{
    use Cake\ORM\Locator\LocatorAwareTrait;

    // ...
    
    public function buildRules(RulesChecker $rules): RulesChecker
    {
        // ...

        $contractorsTable = $this->getTableLocator()->get('Contractors');

        return $rules;
    }
}

Not sure if your schema is the best solution for your problem domain, so I'm not really going to comment on that, just a note that it looks somewhat unoptimized with all that duplicate fields.

Source