2

In I could not access Controller's view action for composite primary key table. (http://localhost:8765/invoice-items/view/1)

enter image description here

Here are samples of the code created by cake bake:

InvoiceItemsTable calss in which the primary key is defined as composite.

class InvoiceItemsTable extends Table
{
    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config): void
    {
        parent::initialize($config);

        $this->setTable('invoice_items');
        $this->setDisplayField(['item_id', 'invoice_id', 'unit_id']);
        $this->setPrimaryKey(['item_id', 'invoice_id', 'unit_id']);

        $this->addBehavior('Timestamp');

        $this->belongsTo('Items', [
            'foreignKey' => 'item_id',
            'joinType' => 'INNER',
        ]);
        $this->belongsTo('Invoices', [
            'foreignKey' => 'invoice_id',
            'joinType' => 'INNER',
        ]);
        $this->belongsTo('Units', [
            'foreignKey' => 'unit_id',
            'joinType' => 'INNER',
        ]);
    }
...

InvoiceItemsController view method:

/**
     * View method
     *
     * @param string|null $id Invoice Item id.
     * @return \Cake\Http\Response|null|void Renders view
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function view($id = null)
    {
        $invoiceItem = $this->InvoiceItems->get($id, [
            'contain' => ['Items', 'Invoices', 'Units'],
        ]);

        $this->set(compact('invoiceItem'));
    }

Finally a screen shot of invoice_items table structure from phpmyadmin:

enter image description here

I have tried to access the view like (http://localhost:8765/invoice-items/view/1,1,6) but I got the same error ... with primary key ['1,1,6']. I do not know how to represent the composite primary key in the URL? or what is the problem?

I use CakePHP version 4.4.2

SaidbakR
  • 13,303
  • 20
  • 101
  • 195

1 Answers1

1

Table::get() expects composite keys to be passed as arrays, eg [1, 1, 6].

Assuming you're using the fallback routes from the default app skeleton, you can pass additional arguments as path parts, eg:

/invoice-items/view/1/1/6

and accept them in your controller action like:

public function view($itemId, $invoiceId, $unitId)

and build an array from the accordingly to pass to get() as the "id":

$this->InvoiceItems->get([$itemId, $invoiceId, $unitId], /* ... */)

In case you're using custom routes with fixed parameters, add additional ones in whatever form you like, for example with dashes:

$routes
    ->connect(
        '/invoice-items/view/{itemId}-{invoiceId}-{unitId}',
        ['controller' => 'InvoiceItems', 'action' => 'view']
    )
    ->setPass(['itemId', 'invoiceId', 'unitId'])
    ->setPatterns([
        'itemId' => '\d+',
        'invoiceId' => '\d+',
        'unitId' => '\d+',
    ]);

then your URL would look like:

/invoice-items/view/1-1-6

See also

ndm
  • 59,784
  • 9
  • 71
  • 110
  • I don't use custom routes. The parameters are url encoded like `1%2F1%2F6` it works but I just need them to be `1/1/6` without encoding. – SaidbakR Jul 26 '22 at 23:40