cakephp 3.0 how to populate a select field with values instead of id

Raul Magdalena Catala picture Raul Magdalena Catala · Jun 19, 2015 · Viewed 18.3k times · Source

i was looking for a previous answer, but the ones i've found are related to older cakephp versions

i have two tables, 'magazines' and 'issues' where there is a relation 'issues' BelongsTo 'magazines', this is what IssuesTable looks like:

public function initialize(array $config){

$this->belongsTo('Magazines', [
    'foreignKey' => 'id'
]);
}

table magazines has two fields, magazines.id and magazines.name

table issues has two fields, issues.id, issues.magazine_id where issues.magazine_id is the foreign key

to populate a select input in the issues view with the magazine.name values and save the issues.magazine_id, i've set the controller like this

$this->set('magazines', $this->Issue->Magazine->find('list'));

then i've added the following code to the issue view add.cpt

    <?php
    echo $this->Form->input('name', [
    'type' => 'select',
    'multiple' => false,
    'options' => $magazines, 
    'empty' => true]);
    ?>

but i get the input select with the issues.magazine_id as values instead of magazines.name

thanks for your help and comments

Answer

drmonkeyninja picture drmonkeyninja · Jun 20, 2015

You want to use find('list') as this will return the primary key and display field:-

$this->set(
    'magazines', 
    $this->Issues->Magazines->find('list')
);

Then in your form you need the input name to be magazine_id if you're wanting to set the foreign key for the association:-

echo $this->Form->input(
    'magazine_id', 
    [
        'type' => 'select',
        'multiple' => false,
        'options' => $magazines, 
        'empty' => true
    ]
);

See the docs for more info.

Update

If you're experiencing issues with find('list') it is perhaps because your model's displayField is not getting set correctly. Cake normally determines the displayField for the model on initialisation. If this isn't working, or you want a different field you can set this manually in the model's initialize() method. E.g.:-

class MagazinesTable extends Table
{

    public function initialize(array $config)
    {
        $this->displayField('name');
    }
}

Changing 'name' to the appropriate field.

Alternatively, you can choose which field Cake will use for the values returned by find('list') (this is particularly useful when you want to override the default displayField). E.g.:-

$this->Issues->Magazines->find('list', [
    'keyField' => 'id',
    'valueField' => 'name'
]);