I have the Three tables:
- Samples
- Tests
- Results
My aim is to develop associations between them so that:
A sample can have many tests and a test can have one result. (A sample has many tests and another sample can also has same tests, on the other hand a test has one result and the same test for another sample can have a different result. )
Here is my Sample Table:
+----+---------+-------+
| ID | Name | Type |
+----+---------+-------+
| 1 | Sample1 | Type1 |
+----+---------+-------+
| 2 | Sample2 | Type2 |
+----+---------+-------+
Here is my Tests Table:
+----+---------+
| ID | Name |
+----+---------+
| 1 | Test1 |
+----+---------+
| 2 | Test2 |
+----+---------+
Here is my Results Table:
+----+-------+
| ID | Value |
+----+-------+
| 1 | 1.22 |
+----+-------+
| 2 | 909 |
+----+-------+
I've combined the samples and tests table and created a separate table called samples_tests.
Here is the structure of samples_tests table:
+----+-----------+---------+
| ID | sample_id | test_id |
+----+-----------+---------+
| 1 | 2 | 4 |
+----+-----------+---------+
| 2 | 3 | 4 |
+----+-----------+---------+
| 3 | 3 | 2 |
+----+-----------+---------+
Both the sample_id and test_id are foreign keys.
Here is my association in SamplesTable.php
$this->belongsToMany('Tests', [
'foreignKey' => 'sample_id',
'targetForeignKey' => 'test_id',
'joinTable' => 'samples_tests'
]);
Here is my association in TestsTable.php
$this->belongsToMany('Samples', [
'foreignKey' => 'test_id',
'targetForeignKey' => 'sample_id',
'joinTable' => 'samples_tests',
'dependent' => true,
'cascadeCallbacks' => true
]);
Its working pretty fine, but now i have to introduce the results part and i'm stuck on how to define the associations now.
Any help would be appreciated.
As suggested by @CbNrZvWd I've tried this:
$table = $this->table('samples_tests_results', ['id' => false, 'primary_key' => ['sample_id', 'test_id', 'result_id']]);
$table
->addColumn('sample_id', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
])
->addColumn('test_id', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
])
->addColumn('result_id', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
])
->addIndex(
[
'result_id',
]
)
->addIndex(
[
'sample_id',
]
)
->addIndex(
[
'test_id',
]
)
->create();
$this->table('samples_tests_results')
->addForeignKey(
'result_id',
'results',
'id',
[
'update' => 'RESTRICT',
'delete' => 'RESTRICT'
]
)
->addForeignKey(
'sample_id',
'samples',
'id',
[
'update' => 'RESTRICT',
'delete' => 'RESTRICT'
]
)
->addForeignKey(
'test_id',
'tests',
'id',
[
'update' => 'RESTRICT',
'delete' => 'RESTRICT'
]
)
->update();
But doing so adds the following complexity:
When i add new sample, i also select tests from a multi select dropdown. But it also asks for results in order to successfully save sample.
What i went is to save the sample with tests and add the results later on whenever i want.
Results and Tests have a one to one relation.
add a test_id field to your results table
then in ResultsTable initialize method set up the relation:
$this->hasOne('Results');
http://book.cakephp.org/3.0/en/orm/associations.html#hasone-associations
and you can store additional data in the samples_tests table:
ID | sample_id | test_id | result_id
http://book.cakephp.org/3.0/en/orm/associations.html#using-the-through-option