I have a mysql table with composite keys ( user_id , category_id ); I am trying to update the last access for these records as following
$userCategory = new UserCategory;
$userCategory->user_id = 1;
$userCategory->category_id = 15;
echo $userCategory->isNewRecord; //always true
$userCategory->last_access = Now();
$userCategory->save();
The {$userCategory->isNewRecord} and when I try to save() the MySQL generates a duplicate error for the composite Primary keys.
I also added this to UserCategory model but didn't help
public function primaryKey() {
return array('user_id', 'category_id');
}
****Update: Sorry for the confusion. My question is how to achieve the same result as "ON DUPLICATE KEY UPDATE" in the Yii framework. In other words, how to do the insert or update in one SQL query. if you look at the source code for 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;
}
Actually, the problem is that if isNewRecord
is always true, it means that Yii is going to use an INSERT
statement instead of an UPDATE
statement when saving the model to the database.. that is why you always get the duplicate pk error, even if it's composite.
Here is the official documentation about IsNewRecord
. So, the problem is that you're using
$userCategory = new UserCategory; //Always a new record, tries to INSERT
So to resolve this you have to find the record and evaluate if it is found before saving it, instead. Documentation can also be read Here about the find()
family of methods and their return value, the return values of the find() methods vary slightly on their nature:
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.
You can use this return value to differentiate wether a primary key exists or not:
$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();
This will ensure that the framework uses the INSERT or UPDATE statement correctly, avoiding the duplicate PK error you're getting.
Edit: Enhanced the example code to properly populate the record when it's new.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With