</> Code The Pixel

CakePHP 4 Insert, Save, Update (hasOne) Associative Data

Asyraf Wahi Anuar - January 27, 2021

Estimated reading time: 3 minutes, 37 seconds

Insert, save and edit the associative data is a common process in web applications. Most of the related associative data is based on the ‘hasMany’ relationship. However, in this tutorial, the focus is on the ‘hasOne’ relationship e.g user has one profile. Technically, some of the developers combined the user profile information into the same user table. However, if the user profile comprises lots of data, it is recommended to separate the storage to make it more systematic. The following tutorial will guide you on how to insert, save and edit the associated data.

There are 2 tables used as a sample for this tutorial as shown below:

Table: users

Table: profiles

Relationship: User has one profile

Define Relationship
First, define the relationship and ensure that it has a correct relationship.
File: UsersTable.php:
Location: .../src/Model/Table

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

    //...others relationship
    $this->hasOne('Profiles'); //User has one profile. If table name: user_profiles used UserProfiles
}


File: ProfilesTable.php:
Location: .../src/Model/Table
public function initialize(array $config): void

{
    parent::initialize($config);
    
    //...others relationship
    $this->belongsTo('Users', [
        'foreignKey' => 'user_id',
        'joinType' => 'INNER',
    ]);
}


Associated Input Field
The visible input in the add function is username, password, email, status. To include the profile input (fullname, dob and gender) into user add page, simply add the input field as follows:
File: add.php
Location:.../templates/Users

<?php
    echo $this->Form->control('username');
    echo $this->Form->control('password');
    echo $this->Form->control('email');
    echo $this->Form->control('status');
    echo $this->Form->control('profile.fullname'); //If table name: user_profiles use user_profile.fullname
    echo $this->Form->control('profile.dob');
    echo $this->Form->control('profile.gender');
?>


Saving Associated Data
Then to save the associated data to the Profiles table, add the following codes into UsersController.
File: UsersController.php
Location:.../src/Controller
public function add()

{
    $user = $this->Users->newEmptyEntity();
    if ($this->request->is('post')) {
        $user = $this->Users->patchEntity($user, $this->request->getData());
        if ($this->Users->save($user, ['associated' => ['Profiles']])) { //Save Associated to Profiles table. If table name: user_profiles used UserProfiles
            $this->Flash->success(__('The user has been saved.'));

            return $this->redirect(['action' => 'index']);
        }
        $this->Flash->error(__('The user could not be saved. Please, try again.'));
    }
    $this->set(compact('user'));
}


Set Accessible: Profile Table
File: User.php
Location:.../src/Model/Entity

protected $_accessible = [
    'username' => true,
    'password' => true,
    //others fields
    'profile' => true, //profile fields. If table name: user_profiles used user_profile
];


View Profile Information
To view the profile information, the user's view controller needs to get the user profile based on user_id as shown below:
File: UsersController.php
Location:.../src/Controller

public function view($id = null)
{
    $user = $this->Users->get($id, [
        'contain' => ['Profiles'],
    ]);

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


In your user view page, call the related profile information that you required using the following codes:
File: view.php
Location:.../templates/Users

<?= h($user->profile->fullname) ?> <!--if table user_profiles use user_profile->fullname


Edit Associated Data
To edit the associative data from the user edit view, the public function edit in the users' controller needs to get the profiles information based on the user_id, then  save the associated data as shown below:
File: UsersController.php
Location:.../src/Controller

public function edit($id = null)
{
    $user = $this->Users->get($id, [
        'contain' => ['Profiles'],
    ]);
    
    if ($this->request->is(['patch', 'post', 'put'])) {
        $formdata = $this->getRequest()->getData();
        $user = $this->Users->patchEntity($user, $formdata,['associated'=>['Profiles']]); //If table name user_profiles use UserProfiles
        if ($this->Users->save($user)) {
            $this->Flash->success(__('The user has been saved.'));

            return $this->redirect(['action' => 'index']);
        }
        $this->Flash->error(__('The user could not be saved. Please, try again.'));
    }
    
    $this->set(compact('user'));
}


The following codes are used to recall the profile value in edit input (same as add.php):
File: edit.php
Location:.../templates/Users

echo $this->Form->control('profile.fullname'); //If table name: user_profiles use user_profile.fullname
echo $this->Form->control('profile.dob');
echo $this->Form->control('profile.gender');


That all. Happy coding :)


Cite this article (APA 6th Edition)

Popular
CakePHP 4 Print PDF Using CakePDF
May, 17 2020
CakePHP 4 Authentication Using Auth...
May, 14 2020
CakePHP 4 Sending Email
February, 01 2022
CakePHP 4 jQuery Date Time Picker
October, 01 2018
CakePHP 4 Export To CSV
May, 29 2020
CakePHP 4 Authentication Using...
May, 11 2020
CakePHP 4 Find, Sort & Count
June, 02 2020
Share
Sharing Link
Click the icon to share