Cakephp 在更改字段时更新另一个 table
Cakephp update another table on change of a field
我有 2 个 table:客户和资产分配。
客户 table 有一个字段:is_active。
在编辑模式下,当 is_active 从 TRUE 更改为 FALSE 时,我需要通过为所有 assets_assignations 设置 end_date=TODAY 来更新分配 table选定的客户。
AssetsAssignations 包含以下字段:(id, asset_id, client_id, room_id, ip_address, starting_date, ending_date)。在资产分配表中:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('assets_assignations');
$this->displayField('id');
$this->primaryKey('id');
$this->belongsTo('Assets', [
'foreignKey' => 'asset_id'
]);
$this->belongsTo('Clients', [
'foreignKey' => 'client_id'
]);
$this->belongsTo('Rooms', [
'foreignKey' => 'room_id'
]);
}
在客户表中:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('clients');
$this->DisplayField('full_name');
$this->primaryKey('id');
$this->hasMany('AssetsAssignations', [
'foreignKey' => 'client_id'
]);
....
}
这是我为客户编辑的功能:
public function edit($id = null)
{
$client = $this->Clients->get($id, [
'contain' => []
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$client = $this->Clients->patchEntity($client, $this->request->data);
if ($this->Clients->save($client)) {
$this->Flash->success(__('The client has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The client could not be saved. Please, try again.'));
}
$clientTypes = $this->Clients->ClientTypes->find('list', ['limit' => 200]);
$this->set(compact('client', 'clientTypes'));
$this->set('_serialize', ['client']);
}
我的推荐:
在ClientsTable.php中添加
use ArrayObject;
use Cake\Datasource\EntityInterface;
use Cake\Event\Event;
use Cake\I18n\FrozenDate;
/**
* Perform additional operations after it is saved.
*
* @param \Cake\Event\Event $event The afterSave event that was fired
* @param \Cake\Datasource\EntityInterface $entity The entity that was saved
* @param \ArrayObject $options The options passed to the save method
* @return void
*/
public function afterSave(Event $event, EntityInterface $entity, ArrayObject $options) {
// For CakePHP 3.4.3 or later, use isDirty instead of dirty
if (!$entity->isNew() && $entity->dirty('is_active') && !$entity->is_active) {
$this->AssetsAssignations->updateAll(['end_date' => FrozenDate::now()], ['client_id' => $entity->id]);
}
}
通过将这段代码放在 afterSave 事件处理程序中,您可以确保只要 is_active
标志更改为 false,无论更改来自编辑页面还是其他地方,它都会发生。 (现在可能没有其他任何地方更新这个,但是这个未来证明你以防以后添加这样的东西。)
我有 2 个 table:客户和资产分配。 客户 table 有一个字段:is_active。
在编辑模式下,当 is_active 从 TRUE 更改为 FALSE 时,我需要通过为所有 assets_assignations 设置 end_date=TODAY 来更新分配 table选定的客户。
AssetsAssignations 包含以下字段:(id, asset_id, client_id, room_id, ip_address, starting_date, ending_date)。在资产分配表中:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('assets_assignations');
$this->displayField('id');
$this->primaryKey('id');
$this->belongsTo('Assets', [
'foreignKey' => 'asset_id'
]);
$this->belongsTo('Clients', [
'foreignKey' => 'client_id'
]);
$this->belongsTo('Rooms', [
'foreignKey' => 'room_id'
]);
}
在客户表中:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('clients');
$this->DisplayField('full_name');
$this->primaryKey('id');
$this->hasMany('AssetsAssignations', [
'foreignKey' => 'client_id'
]);
....
}
这是我为客户编辑的功能:
public function edit($id = null)
{
$client = $this->Clients->get($id, [
'contain' => []
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$client = $this->Clients->patchEntity($client, $this->request->data);
if ($this->Clients->save($client)) {
$this->Flash->success(__('The client has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('The client could not be saved. Please, try again.'));
}
$clientTypes = $this->Clients->ClientTypes->find('list', ['limit' => 200]);
$this->set(compact('client', 'clientTypes'));
$this->set('_serialize', ['client']);
}
我的推荐:
在ClientsTable.php中添加
use ArrayObject;
use Cake\Datasource\EntityInterface;
use Cake\Event\Event;
use Cake\I18n\FrozenDate;
/**
* Perform additional operations after it is saved.
*
* @param \Cake\Event\Event $event The afterSave event that was fired
* @param \Cake\Datasource\EntityInterface $entity The entity that was saved
* @param \ArrayObject $options The options passed to the save method
* @return void
*/
public function afterSave(Event $event, EntityInterface $entity, ArrayObject $options) {
// For CakePHP 3.4.3 or later, use isDirty instead of dirty
if (!$entity->isNew() && $entity->dirty('is_active') && !$entity->is_active) {
$this->AssetsAssignations->updateAll(['end_date' => FrozenDate::now()], ['client_id' => $entity->id]);
}
}
通过将这段代码放在 afterSave 事件处理程序中,您可以确保只要 is_active
标志更改为 false,无论更改来自编辑页面还是其他地方,它都会发生。 (现在可能没有其他任何地方更新这个,但是这个未来证明你以防以后添加这样的东西。)