CakePHP 3.7
I have 2 model Table classes as follows:
/src/Model/Table/SubstancesTable.php/src/Model/Table/TblOrganisationSubstancesTable.php
The schema for each table in MySQL is as follows:
1.
mysql> describe substances;
+-------------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-----------------------+------+-----+---------+----------------+
| id | mediumint(8) unsigned | NO | PRI | NULL | auto_increment |
| app_id | varchar(8) | NO | UNI | NULL | |
| name | varchar(1500) | NO | | NULL | |
| date | date | NO | | NULL | |
+-------------+-----------------------+------+-----+---------+----------------+
2.
mysql> describe tbl_organisation_substances;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| o_sub_id | int(255) | NO | PRI | NULL | auto_increment |
| o_id | int(255) | NO | MUL | NULL | |
| app_id | varchar(15) | YES | | NULL | |
| os_name | varchar(255) | YES | | NULL | |
| ec | varchar(35) | YES | | NULL | |
| cas | varchar(255) | YES | | NULL | |
| upload_id | int(100) | YES | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
I've written a custom finder which needs to perform a JOIN between these 2 tables. The custom finder looks like this and is in SubstancesTable.php:
public function findDistinctSubstancesByOrganisation(Query $query, array $options)
{
$o_id = $options['o_id'];
$query = $this->find()->select('id')->contain('TblOrganisationSubstances')->where(['TblOrganisationSubstances.o_id' => $o_id]);
return $query;
}
Each table has an app_id column and this is the foreign key that links the 2 tables.
Initially I was getting an error:
The TblOrganisationSubstances association is not defined on Substances.
Which made sense as no definitions had been put in place.
So in SubstancesTable.php I've defined this:
$this->setPrimaryKey('id');
// ...
$this->belongsTo('TblOrganisationSubstances', [
'foreignKey' => 'app_id',
'joinType' => 'INNER'
]);
But this produces the following SQL statement:
SELECT Substances.id AS `Substances__id` FROM substances Substances INNER JOIN tbl_organisation_substances TblOrganisationSubstances ON TblOrganisationSubstances.o_sub_id = (Substances.app_id) WHERE TblOrganisationSubstances.o_id = :c0
This isn't going to work because TblOrganisationSubstances.o_sub_id = (Substances.app_id) is wrong. It needs to JOIN based on app_id, in other words it should be:
TblOrganisationSubstances.app_id = (Substances.app_id)
I also tried changing the belongsTo to a hasMany association (not even sure which one is right here!):
$this->hasMany('TblOrganisationSubstances', [
'foreignKey' => 'app_id',
]);
But the joining doesn't even seem to occur. The SQL produced is:
SELECT Substances.id AS `Substances__id` FROM substances Substances WHERE TblOrganisationSubstances.o_id = :c0
I also tried putting a belongsTo in TblOrganisationSubstances.php to try and define the relationship from both sides:
$this->belongsTo('Substances', [
'foreignKey' => 'app_id',
'joinType' => 'INNER'
]);
Again, this doesn't work. It produces the SQL without the join.
Please can someone help in terms of advising which is the correct type of association (hasMany vs belongsTo) and how to perform the join based on app_id, which is the foreign key that links the 2 tables.