Joining 3 tables with a junction table (HABTM) - cakephp

We have 3 tables - items, locations and taxes. items_locations and locations_taxes are already associated. But, there is a need to connect all of them - items_locations_taxes
Database schema is already in place. When I baked locations model, it did something like this :
$this->belongsToMany('LocationsTaxes', [
'foreignKey' => 'location_id',
'targetForeignKey' => 'locations_tax_id',
'joinTable' => 'items_locations_taxes'
]);
$this->belongsToMany('Items', [
'foreignKey' => 'location_id',
'targetForeignKey' => 'item_id',
'joinTable' => 'items_locations'
]);
$this->belongsToMany('Taxes', [
'foreignKey' => 'location_id',
'targetForeignKey' => 'tax_id',
'joinTable' => 'locations_taxes'
]);
First belongsToMany seems to be wrong. Its auto generated through Bake.
Now, how can these 3 be connected through join?
And, take a note that junction tables are using composite primary keys and do not contain id column.

Related

Unable to save associated (hasOne) data

I am creating a simple API with CakePHP 4, and I am having some issues saving some POST data. This is a new project, so the models are newly baked, based on my 3 tables: elaborations, details, jobs
The ElaborationTable table has these relations:
$this->hasOne('Details', [ // this (and the next) is the only thing that I've manually changed here: hasOne instead of hasMany
'foreignKey' => 'elaboration_id',
]);
$this->hasOne('Jobs', [
'foreignKey' => 'elaboration_id',
]);
While both DetailsTable and JobsTable have this:
$this->belongsTo('Elaborations', [
'foreignKey' => 'elaboration_id',
'joinType' => 'INNER',
]);
In my controller, this is what I'm using to retrieve the POST data and save it to each database table:
$data = $this->request->getData();
$data['user_id'] = $this->Auth->user('id');
$elaboration = $this->Elaborations->newEntity($data, [
'associated' => [
'Details',
'Jobs'
]
]);
Finally, my POST data is something like this:
APP/Controller/ElaborationsController.php (line 85)
[
'detail' => [
'regione' => 'Lazio',
'provincia' => 'RM',
'comune' => 'Roma',
],
'job' => [
'serramenti' => '1',
],
'user_id' => (int) 2,
]
Now, the user_id field gets saved in my elaborations table, no errors are issued, but still the details and jobs tables remains empty, no data is saved.
What am I doing wrong?

cakephp belongsToMany with 4 tables

We have 4 tables
Users
-id
Profiles
-id
-user_id
Questions
-id
Options
-id
ProfileQuestions
-id
-profile_id
-question_id
-option_id
Now i require to get all profiles and each profile have multiple questions and each question has many options.
User Model
$this->hasMany('Profiles', [
'foreignKey' => 'user_id'
]);
Profiles Model
$this->belongsToMany('Questions', [
'foreignKey' => 'profile_id',
'targetForeignKey' => 'question_id',
'joinTable' => 'profile_questions',
'through' => 'ProfileQuestions' ,
'joinType' => 'LEFT']);
Questions Model
$this->belongsToMany('Options', [
'foreignKey' => ['question_id'],
'targetForeignKey' => 'option_id',
'joinTable' => 'profile_questions',
'through' => 'ProfileQuestions'
]);
ProfileQuestions Model
$this->belongsTo('Profile', [
'foreignKey' => 'profile_id',
]);
$this->belongsTo('Questions', [
'foreignKey' => 'question_id'
]);
$this->belongsTo('Options', [
'foreignKey' => 'option_id'
]);
Controller code to get the result
$query = $this->Users->find('first')
$query->contain(['Profiles.Questions.Options']);
Error
Fatal error: Out of memory (allocated 408944640) (tried to allocate 665912212 bytes) in vendor\cakephp\cakephp\src\Database\Statement\MysqlStatement.php on line 39
Issue is related to Associations. If we set the profile_id where condition with the options contain then it works for that profile id.

Cakephp 3 : How to fetch joing table associated data?

I have a table name countries , countries has relation with users, users has relation with MoneyTransferTransactions
In MoneyTransferTransactions view I need fetch country name.
I already join Users table in MoneyTransferTransactionsTable by below code
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
In user table I also used inner join like below code
$this->belongsTo('Countries', [
'foreignKey' => 'country_id',
'joinType' => 'INNER'
]);
In MoneyTransferTransactions controller I have used below code to fetch all data with associated data.
$this->paginate = [
'contain' => ['Users','TransferOptions'],
'conditions'=> ['MoneyTransferTransactions.status'=>1],
'order' =>['MoneyTransferTransactions.id'=>'DESC']
];
I have used var_dump in index.ctp , I gotted country id from users table but not got country name from countries table. How can I get country name from MoneyTransferTransactions>index.ctp ?
Add association between Users and Countries in 'contain'
$this->paginate = [
'contain' => ['TransferOptions', 'Users' => ['Countries']],
'conditions' => ['MoneyTransferTransactions.status' => 1],
'order' => ['MoneyTransferTransactions.id' => 'DESC']
];

Linking two tables with two (composite) foreign key relation

Version: 3.2.1
Relations
Two columns from table B are associated with two columns from table A.
Table A -> hasMany -> table B
Table B -> belongsTo -> table A
B.a_id = A.a_id
B.a_name = A.a_name
Cookbook
No example found in the cookbook.
http://book.cakephp.org/3.0/en/orm/associations.html
How can I specify these relations? Already tried this:
$this->hasMany('B', [
'conditions' => ['A.a_id' => 'B.a_id', 'A.a_name' => 'B.a_name']
]);
And this:
$this->hasMany('B1', [
'foreignKey' => 'a_id',
'joinType' => 'INNER',
'className' => 'B'
]);
$this->hasMany('B2', [
'foreignKey' => 'a_name',
'joinType' => 'INNER',
'className' => 'B'
]);
Composite keys can be specified using arrays, this is supported for foreign keys as well as primary keys nearly everywhere.
$this->hasMany('B', [
'foreignKey' => [
'a_id',
'a_name'
],
'bindingKey' => [
'a_id',
'a_name'
]
]);
An example in the docs wouldn't hurt, you may want to open a ticket over at GitHub.
ps. hasMany associations do not support a joinType option.

CakePHP: self-referencing HABTM associations?

I want to create HABTM self-associations. That is, Users can be associated with other users. The problem is this: I can save associations from one User to another, but I can only view and edit those associations one way. Here's my association:
'Partner' => array(
'className' => 'User',
'joinTable' => 'players_trainers',
'associationForeignKey' => 'player_id',
'foreignKey' => 'trainer_id',
'unique' => true
)
So when I call a User (who is a trainer) I can see the players that are associated with them. No sweat. But when trying to view/edit associations from the other end (to see which trainers a player has been associated with) nothing appears, because the association is treating every User the same way: expecting to associate from a trainer, to a player.
I thought about doing an on-the-fly binding in my controller (based on user role) but that seems hacky.
Is there a clean way to have a HABTM self-association, without having to add new fields to my model? What am I doing wrong?
Try setting up the other association.
var $hasAndBelongsToMany = array(
'Partner' => array(
'className' => 'User',
'joinTable' => 'players_trainers',
'associationForeignKey' => 'player_id',
'foreignKey' => 'trainer_id',
'unique' => true
),
'Trainer' => array(
'className' => 'User',
'joinTable' => 'players_trainers',
'associatedForeignKey' => 'trainer_id',
'foreignKey' => 'player_id',
'unique' => true
)
);

Resources