cakephp - 删除相关行时将外部列设置为 NULL
问题描述
我有两个可选图片的用户(不要担心逻辑,名称已更改以保护无辜者):
CREATE TABLE users (
id INT(10) NOT NULL AUTO_INCREMENT,
first_name VARCHAR(255),
last_name VARCHAR(255),
first_picture_id INT(10) NULL DEFAULT NULL,
second_picture_id INT(10) NULL DEFAULT NULL,
PRIMARY KEY (id),
CONSTRAINT FK_users_second_picture_id FOREIGN KEY (second_picture_id) REFERENCES pictures (id),
CONSTRAINT FK_users_first_picture_id FOREIGN KEY (first_picture_id) REFERENCES pictures (id)
);
CREATE TABLE pictures (
id INT(10) NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
path VARCHAR(255) NOT NULL,
type VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);
我以这种方式链接了我的模型(我希望那部分是正确的):
class User extends AppModel{
public $belongsTo = array(
'FirstPicture' => array(
'className' => 'Picture',
'foreignKey' => 'first_picture_id',
),
'SecondPicture' => array(
'className' => 'Picture',
'foreignKey' => 'second_picture_id',
),
);
}
class Picture extends AppModel{
public $hasOne = array(
'User',
);
}
现在,当我删除任一图片时:
$this->FirstPicture->delete($this->request->data('FirstPicture.id'));
...我想将 set 中的相应列user
设置为NULL
.
ON DELETE SET NULL
复制外键删除的 CakePHP 习语(如果有的话)是什么?
解决方案
CakePHP 2.x 中没有内置的功能可以自动执行此操作,您必须自己实现它。只要有可能,建议在您的数据库中使用实际的外键约束,但如果这不可能,那么您在这里真的没有太多选择。
beforeDelete
在orafterDelete
事件/回调中这样做应该很容易。如果您的数据库支持事务(并且您的应用程序使用它们 - 它们不会自动发生删除操作),那么beforeDelete
建议您这样做,因为它可以轻松停止删除过程。如果没有事务,这将取决于您在错误情况下更喜欢什么,在没有删除关联记录的情况下将外键设为空 ( beforeDelete
),或者使用非空外键 ( afterDelete
) 删除关联记录。
这是一个简单的示例,您可以从关联的任一方执行此操作Picture
:
public function beforeDelete($cascade = true) {
if (!parent::beforeDelete($cascade)) {
return false;
}
$result = $this->User->updateAll(
array('first_picture_id' => null),
array('first_picture_id' => $this->getID())
);
if (!$result) {
return false;
}
$result = $this->User->updateAll(
array('second_picture_id' => null),
array('second_picture_id' => $this->getID())
);
if (!$result) {
return false;
}
return true;
}
或User
:
public function __construct($id = false, $table = null, $ds = null)
{
parent::__construct($id, $table, $ds);
$this->FirstPicture->getEventManager()->attach(
function () {
return $this->updateAll(
array('first_picture_id' => null),
array('first_picture_id' => $this->FirstPicture->getID())
);
},
'Model.beforeDelete'
);
$this->SecondPicture->getEventManager()->attach(
function () {
return $this->updateAll(
array('second_picture_id' => null),
array('second_picture_id' => $this->SecondPicture->getID())
);
},
'Model.beforeDelete'
);
}
推荐阅读
- c - 在 8-alignment malloc 实现时我们如何处理 header
- sql - Is there a way to calculate correlation between two variables in SQL?
- google-sheets - 在 Google 表格中整理/汇总特定数据的有效方法
- php - PHP MySQL根据列/行值选择多个表
- r - 使用lowess平滑R中的data.table列时出现意外结果
- javascript - 如何将一些信息从一个 get/post 传递到另一个 get/post
- javascript - MongoDB 从日期中挑选数据
- python - Python:获取表中每一行的值的排序位置
- php - 在 WooCommerce 修复问题中购买 x 数量的特定产品类别时,根据用户角色应用折扣
- kubernetes - 入口重定向到 localhost tcp 服务