我正在使用 yii mysql的活动记录,我有一个表,其中有一个字段需要附加同一个表的主键。主键是自动增量字段,因此在保存之前我无法访问主键。
$model->append_field = "xyz".$model->id; // nothing is appending
$model->save();
$model->append_field = "xyz".$model->id; //id is now available
我该怎么做?
我知道我可以在插入后立即更新,但是有更好的方法吗?
答案 0 :(得分:3)
执行INSERT语句后,您的记录仅被分配id
。无法确定INSERT之前的id
是什么,因此 必须在INSERT之后执行带有连接字段值的UPDATE。
您可以在MySQL中编写存储过程或触发器来为您执行此操作,因此您的应用程序会执行单个SQL语句来完成此操作。但是,您只是将逻辑移到MySQL中,最后发生了INSERT和UPDATE。
答案 1 :(得分:3)
更多解决方法:
这几乎是你的方法;)
$model->save();
$model->append_field = "xyz".$model->id; //id is now available
$model->save();
但是你可以使用自定义的afterSave()方法将此功能移动到行为,请注意,你必须注意不要循环事件。
或者只是为它写一个吸气剂
function getFull_append_field(){
return $this->append_field.$this->id;
}
但是你不能在SQL语句中使用它,除非你用CONCAT()或类似的东西在那里创建属性。
答案 2 :(得分:2)
其他任何人对这个问题的看法可能都对我如何实现它感兴趣,所以这里是代码:
//in the model class
class SomeModel extends CActiveRecord{
...
protected function afterSave(){
parent::afterSave();
if($this->getIsNewRecord()){
$this->append_field=$this->append_field.$this->id;
$this->updateByPk($this->id, array('append_field'=>$this->append_field));
}
}
}
避免循环事件的一种方法(如@schmunk所述)是在saveAttributes(...)
方法中使用afterSave()
,但saveAttributes(...)检查 isNewRecord ,并且仅在它是新记录时才插入值,因此要求我们在调用saveAttributes(...)之前使用setNewRecord(false);
。
我发现saveAttributes(...)实际上调用了updateByPk(...)
所以我直接使用了updateByPk(...)本身。