Hello Reader's ,
Hope your are doing good today.
Today in my blog i am going to explain how you can save details with BelongsTo Associations in CakePHP 3.
If you have multiple record for a single user, then you need to split your record into separate tables to reduce duplicate data which help you to maintain wastes storage space.
First your need to create associated table where you will store you data.Here i am using users and user_profiles table for demo you can change according to your requirement.
Step 1 : Create two table in your database.One table for User Credentials another for User details.
//users table
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`email` varchar(128) NOT NULL,
`role` varchar(20) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
`status` int(50) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
);
//user_profiles table
CREATE TABLE `user_profiles` (
`id` smallint(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(50) NOT NULL,
`user_full_name` varchar(255) NOT NULL,
`gender` varchar(255) NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`)
)
Step 2->Create the model for both tables which hold Associations.
//UsersTable Model
Location : "// src/Model/Table/UsersTable.php"
You can defined hasOne Associations inside the initialize method in your model.
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class UsersTable extends Table
{
public function initialize(array $config)
{
$this->addBehavior('Timestamp');
$this->hasOne('UserProfiles'); //A user has one profile.
}
public function validationDefault(Validator $validator)
{
return $validator
->notEmpty('username', 'A username is required')
->notEmpty('password', 'A password is required')
->notEmpty('user_full_name', 'User Full Name is required')
->notEmpty('gender', 'Gender is required')
->add('gender', 'inList', [
'rule' => ['inList', ['male', 'female']],
'message' => 'Please enter a valid gender'
])
->notEmpty('role', 'Role is required')
->add('role', 'inList', [
'rule' => ['inList', ['admin', 'user']],
'message' => 'Please enter a valid role'
]);
}
}
UserProfilesTable Model
Location : "// src/Model/Table/UserProfilesTable.php"
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class UserProfilesTable extends Table
{
public function initialize(array $config)
{
$this->addBehavior('Timestamp');
$this->belongsTo('Users', [
'className' => 'Users',
'foreignKey' => 'user_id',
]);
}
}
After completion above task now create controller where our association will work.
UsersController
Location : "src/Controller/UsersController.php"
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\Event;
use Cake\ORM\Table;
use Cake\ORM\TableRegistry;
class UsersController extends AppController
{
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
}
public function index()
{
$this->layout=false;
$this->set('users', $this->Users->find('all', ['contain' => ['UserProfiles']]));
}
public function add()
{
$this->layout=false;
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->data,['associated' => ['UserProfiles']]);
if ($this->Users->save($user)) {
$this->Flash->success(__('The user has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to add the user.'));
}
$this->set('user', $user);
}
}
Now create your index.ctp and add.ctp file where you can show/add your users details.
index.ctp
Location : "src/Template/Users/index.ctp"
<table border="1" align="center" bgcolor="#F8F8FF">
<tr >
<th colspan="6"><h1>User Info</h1>
<p><?= $this->Html->link("Add New User", ['action' => 'add']) ?></p></br>
</th>
</tr>
<tr>
<th>Id</th>
<th>User ID</th>
<th>User Name</th>
<th>Gender</th>
<th>Password</th>
<th>Created</th>
</tr>
<!-- Here is where we iterate through our $users query object, printing out User info -->
<?php foreach ($users as $user):?>
<tr>
<td><?= $user->id ;?></td>
<td>
<?= $user->username; ?>
</td>
<td>
<?= $user->user_profile->user_full_name; ?>
</td>
<td>
<?= $user->user_profile->gender; ?>
</td>
<td>
<?= $user->password ;?>
</td>
<td>
<?= $user->created->format(DATE_RFC850) ?>
</td>
</tr>
<?php endforeach; ?>
</table>
add.ctp
Location : "src/Template/Users/add.ctp"
<div class="users form">
<?= $this->Form->create($user) ?>
<fieldset>
<legend><?= __('Add User') ?></legend>
<?= $this->Form->input('username') ?>
<?= $this->Form->input('password') ?>
<?= $this->Form->input('user_profile.user_full_name') ?>
<?= $this->Form->input('user_profile.gender', [
'options' => ['male' => 'Male', 'female' => 'Female']
]) ?>
<?= $this->Form->input('role', [
'options' => ['admin' => 'Admin', 'user' => 'User']
]) ?>
</fieldset>
<?= $this->Form->button(__('Submit')); ?>
<?= $this->Form->end() ?>
</div>
I hope this will help you.Please feel free to give us your feedback in comments.
2 Comment(s)