pt0
pt0

Reputation: 175

CakePHP 3 save extra data in join table

The data from $this->request-data needs to be modify, so I cannot use forms directly to populate all tables. All the code had been baked before I added the column "state".

order_id    int(11) PK
part_id int(11) PK
state   varchar(10)

I am getting the ids from $this->request-data and modify it accordingly:

$this->request->data['parts']['_ids'][]=....

The rest goes according to the manual:

$order = $this->Orders->newEntity();
$this->Orders->patchEntity($order, $this->request->data);
$this->Orders->save($order);

I am unable to modify incoming data to save it to the state column

Edit:

the "state" field is still with null value.

OrdersTable

public function initialize(array $config)
{
    parent::initialize($config);

    $this->table('orders');
    $this->displayField('id');
    $this->primaryKey('id');

    $this->addBehavior('Timestamp');

    $this->belongsTo('Users', [
        'foreignKey' => 'user_id',
        'joinType' => 'INNER',
    ]);
    $this->belongsToMany('Parts', [
        'foreignKey' => 'order_id',
        'targetForeignKey' => 'part_id',
        'joinTable' => 'orders_parts',
        'through' => 'OrdersParts',

    ]);
    $this->belongsToMany('Sets', [
        'foreignKey' => 'order_id',
        'targetForeignKey' => 'set_id',
        'joinTable' => 'orders_sets',
    ]);
}

OrdersTable

public function initialize(array $config)
{
    parent::initialize($config);

    $this->table('parts');
    $this->displayField('name');
    $this->primaryKey('id');

    $this->addBehavior('Timestamp');


    $this->belongsTo('Orders', [
        'foreignKey' => 'order_id',
        'joinType' => 'INNER',
    ]);

    $this->belongsToMany('Orders', [
        'foreignKey' => 'part_id',
        'targetForeignKey' => 'order_id',
        'joinTable' => 'orders_parts',

    ]);

    $this->belongsToMany('States', [
        'foreignKey' => 'part_id',
        'targetForeignKey' => 'state_id',
        'joinTable' => 'parts_states'
    ]);
}

Insert:

$order = $this->Orders->newEntity();
$order->status = 'new';
$order->user_id = $this->Auth->user('id');
$this->request->data['parts'][0]['_joinData']['state'] = "whatever";
$this->Orders->patchEntity(
$order,
$this->request->data,
['associated' => ['Sets','Parts._joinData']]
);

$this->Orders->save(
$order,
['associated' => ['Sets','Parts._joinData']]
);

I had to include aslo SetsModel into the associated.

Upvotes: 2

Views: 1978

Answers (1)

Corentin Bruneau
Corentin Bruneau

Reputation: 146

$this->request->data['parts']['_ids'] allows you to join tables but you cannot add data this way. In order to do so, your $this->request->data['parts'] structure will have to be like the following :

'parts' => [
    0 => [
        'id'=> 1,
        '_joinData' => [
            'state' => 'exampleSate'
        ]
    ]
]

Make sure you don't have the '_ids' array in your 'parts' array anymore, otherwise you won't be able to save data to your join table.
The 'id' field corresponds to the id of the concerned Part. To set it :

$this->request->data['parts'][0]['id'] = <idOfTheConcernedPart>;


To set your 'state' field, just do :

$this->request->data['parts'][0]['_joinData']['state'] = "whatever";

Finally you'll need to tell cakephp that you are saving some _joinData by adding some configs to you patchEntity and save methods :

$this->Orders->patchEntity(
    $order, 
    $this->request->data, 
    ['associated' => ['Parts._joinData']]
);

$this->Orders->save(
    $order, 
    ['associated' => ['Parts._joinData']]
);

I hope it helps,
cheers.

Upvotes: 7

Related Questions