CakePHP 3 Tutorial 19: Display One Thing, Save Another

Submitted by naidim on Tue, 10/25/2016 - 13:37

There may come a case, as in the previous tutorial (CakePHP 3 Tutorial 18: Autocomplete) that you want to display one thing in a form field, yet save a different value. In the previous case, you select a user's name from an autocomplete list, yet the user's id is the value you want to save in the database.

1. Save The Correct Data

What you want to do is modify the request data before building the entity (CakePHP 3 Book).

In your associated model, in our case the phone numbers table model (/src/Model/Table/PhoneNumbersTable.php) add the following:

use Cake\Event\Event;
use ArrayObject;
use Cake\ORM\TableRegistry;

Then build the beforeMarshal() function to take the input of user->full_name and convert it to user->id

public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options)
    if (isset($data['user_id'])) {
        $users = TableRegistry::get('Users');
        $query = $users->find()
            ->where(['full_name' => $data['user_id']])
        $data['user_id'] = $query['id'];

And lastly set our users getAll() function to use the full_name as the value as well as the label.

$resultsArr[] =['label' => $result['full_name'], 'value' => $result['full_name']];

2. Display The Desired Data

At this point the form allows you to select and display the full_name, but when you load a phone_number to edit it still displays the user id.

In the phone numbers controller (/src/Controller/PhoneNumbersController.php) ensure that when you get your phone number for editing it "contains" the user.

public function edit($id = null)
    $phoneNumber = $this->PhoneNumbers->get($id, [
        'contain' => ['Users']

Then in the "edit" view (/src/Template/PhoneNumbers/edit.ctp) set the value you want for the field, overriding the default value.

$this->Form->input('user_id', ['type' => 'text', 'value' => $phoneNumber->user->full_name]);

Next: Obscure URLs

Add new comment