php – 使用isNewRecord的Yii复合主键

我有一个带有复合键的 mysql表(user_id,category_id);
我正在尝试更新这些记录的最后一次访问,如下所示
$userCategory = new UserCategory;
$userCategory->user_id = 1;
$userCategory->category_id = 15;
echo $userCategory->isNewRecord; //always true
$userCategory->last_access = Now();

$userCategory->save();

{$userCategory-> isNewRecord}当我尝试save()时,MysqL会为复合主键生成重复错误.

我还将此添加到UserCategory模型但没有帮助

public function primaryKey() {
        return array('user_id','category_id');
    }

****更新:
对困惑感到抱歉.我的问题是如何在Yii框架中实现与“ON DUPLICATE KEY UPDATE”相同的结果.换句话说,如何在一个SQL查询中插入或更新.如果你看一下save()的源代码

public function save($runValidation=true,$attributes=null)
{
    if(!$runValidation || $this->validate($attributes))
        //checking if new record
        return $this->getIsNewRecord() ? $this->insert($attributes) : $this->update($attributes);**
    else
        return false;
}
实际上,问题是如果isNewRecord始终为true,则意味着在将模型保存到数据库时,Yii将使用INSERT语句而不是UPDATE语句.这就是为什么你总是得到重复的pk错误,即使这是复合材料.

Here是关于IsNewRecord的官方文档.所以,问题是你正在使用

$userCategory = new UserCategory; //Always a new record,tries to INSERT

因此,要解决此问题,您必须找到记录并评估是否在保存之前找到它,而不是.关于find()系列方法及其返回值的文档也可以在Here中阅读,find()方法的返回值在性质上略有不同:

find..() returns the record found or NULL if no record is found.

findAll..() returns an array containing all the records found or an empty array if no records are found.

您可以使用此返回值来区分是否存在主键:

$userCategory = UserCategory::model()->findByAttributes(array('user_id '=>1,'category_id '=>15));
// if user does not exist,you need to create it
if ($userCategory == NULL) {
     $userCategory = new UserCategory;
     $userCategory->user_id = 1;
     $userCategory->category_id = 15;
}
echo $userCategory->isNewRecord; //you will see the difference if it does exist or not exist
$userCategory->last_access = Now();
$userCategory->save();

这将确保框架正确使用INSERT或UPDATE语句,从而避免您获得的重复PK错误.

编辑:增强了示例代码,以便在新记录时正确填充记录.

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...