I built the basic version of my application, and now I need to integrate an additional datasource, but this one does not conform to CakePHP’s naming conventions, and I cannot alter the structure of it, since there is third-party Java code that relies on that structure. My thought here was to build a CakePHP plugin to use that datasource. Thankfully, their database has a nearly-compliant structure.
Specifically, the associative tables don’t conform. Here’s an example with placeholder names:
durps: id, name, value
blahs: id, name, value
durpsblahs: durps_id, blahs_id
users: id, name
usersdurps: users_id, durps_id
So, the users, durpsblahs, and usersdurps tables are the ones that are the issue here.
My issue with the users table is that I need to link my existing User entity and table models to the new one. With the associative tables, the names are not underscore separated, but, since the two columns in those tables have foreign key constraints, CakePHP only party treats those tables as associative. For example, I added one Durp, and one Blah, but the Add Durpsblahs page has no controls to either enter the values for durps_id and blahs_id or select them from dropdown menus. I can CRUD the base entities just fine.
My questions:
What parts of the generated code for Durpsblahs (entity and table models) do I need to modify?
How do I modify my original User entity and table models to link to the new FancyPlugin\User models?
For your question #1
You can change the table name in your /src/Model/Table/DurpsBlahsTable.phpinitialize() method by invoking $this->table('durpsblahs');
1 <?php`
2 namespace DBAuth2\Model\Table;
3
4 use Cake\ORM\Query;
5 use Cake\ORM\RulesChecker;
6 use Cake\ORM\Table;
7 use Cake\Validation\Validator;
8 use DBAuth2\Model\Entity\Durpsblah;
9
10 /**
11 * Durpsblahs Model
12 *
13 * @property \Cake\ORM\Association\BelongsTo $Durps
14 * @property \Cake\ORM\Association\BelongsTo $Blahs
15 */
16 class DurpsblahsTable extends Table
17 {
18
19 /**
20 * Initialize method
21 *
22 * @param array $config The configuration for the Table.
23 * @return void
24 */
25 public function initialize(array $config)
26 {
27 parent::initialize($config);
28
29 $this->table('durpsblahs');
30 $this->displayField('durps_id');
31 $this->primaryKey(['durps_id', 'blahs_id']);
32
33 $this->belongsTo('Durps', [
34 'foreignKey' => 'durps_id',
35 'joinType' => 'INNER',
36 'className' => 'DBAuth2.Durps'
37 ]);
38 $this->belongsTo('Blahs', [
39 'foreignKey' => 'blahs_id',
40 'joinType' => 'INNER',
41 'className' => 'DBAuth2.Blahs'
42 ]);
43 }
44
45 /**
46 * Returns a rules checker object that will be used for validating
47 * application integrity.
48 *
49 * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
50 * @return \Cake\ORM\RulesChecker
51 */
52 public function buildRules(RulesChecker $rules)
53 {
54 $rules->add($rules->existsIn(['durps_id'], 'Durps'));
55 $rules->add($rules->existsIn(['blahs_id'], 'Blahs'));
56 return $rules;
57 }
58
59 /**
60 * Returns the database connection name to use by default.
61 *
62 * @return string
63 */
64 public static function defaultConnectionName()
65 {
66 return 'dbauth_module';
67 }
68 }`
I see that the table model is using the composite key, so, that’s good. It looks like it should just work from there, but, as the generated code shows on line 29 above, it’s already using the correct table.
Yes, there are two “users” tables: one in my base application, and the 3rd party Java module has its own database, which includes a “users” table.
That module does not perform user management, so I want to be able to perform that within my application. Since I cannot modify their database without “breaking” the module, I need a way to link the two User models together.
Using a plugin, so I don’t have to do some silly renaming of the secondary user model E V E R Y W H E R E. I thought that it would be much easier to simply refer to the plugin user model like this: DBAuth2\User
Please, correct me if am mistaken in this assumption.
@markstory, I tried your suggestion. I created a row in “durps”, one in “blahs”, and one in the associative table, “durpsblahs”.
mysql> SELECT * FROM durps;
+----+----------+
| id | name |
+----+----------+
| 0 | durp zero |
+----+----------+
1 row in set (0.00 sec)
mysql> SELECT * FROM blahs;
+----+----------+
| id | name |
+----+----------+
| 0 | blah zero |
+----+----------+
1 row in set (0.00 sec)
mysql> SELECT * FROM durpsblahs;
+----------+----------+
| durps_id | blahs_id |
+----------+----------+
| 0 | 0 |
+----------+----------+
1 row in set (0.00 sec)
When I go to “/dbauth2/durpsblahs/view/0/0” I get the following error:
Record not found in table “durpsblahs” with primary key [‘0’]
Why don’t you create your user table (base app) with one-one connection with the existing user table (java module)?
In the same time you can create model, controller and views for the java module users table also in your app. In the end it is just a database table and you can read and write it from more sources, eg from java and from your base app - if it helps you in your situation.
OK, crisis averted. I spoke with the module vendor, and they’ve agreed to the changes that I requested for the Java module’s database structure. So, I can simply added the properly named tables to my application’s database, and add the appropriately named columns to my application’s “users” table. Along with that, the proper keys and constraints.