Difference between #4 and #5 of
Using updateAll and deleteAll with scopes

Revision #5 has been created by le_top on Aug 12, 2014, 6:15:24 AM with the memo:

Typo corrections + titles added + some rewrites
« previous (#4)

Changes

Title unchanged

Using updateAll and deleteAll with scopes

Category unchanged

How-tos

Yii version unchanged

Tags unchanged

updateAll, deleteAll, scopes, conditions

Content changed

This article is about how to use Using _CActiveRecord->updateAll()_ and _CActiveRecord->deleteAll()_ with scopes and criteria almost like you are used to with  _findAll()_ , _find()_ and the other retrieval methods.
 
 
Those amongst you that
requires some _tricks_ that are explained in this article.  While _findAll()_ , _find()_ and some other methods use scopes automatically, _updateAll()_ and _deleteAll()_ do not.
 
 
The limitation of _updateAll()_ and _deleteAll()_
 
--------------------------------------------------
 
 
If you
tried, you will know that while these functions allow you to specify a $condition as a parameter, but that they do not use the conditions and scopes that you may have defined on the model().
In other words, the next code does not behave as you might expect:
[...]
This behavior is by design and has been subject to discussions on the forum, etc.

The solution
 
------------
 
 
Fortunately, there is a way to use the wonderful feature to define scopes and conditions in a high level manner. The trick is to extract the criteria by using _applyScopes()_. The issue is that _applyScopes()_ will suppose an alias 't' for the table. And that breaks the SQL query as the _updateAll()_ and _deleteAll()_ methods do not apply an alias to the table you are updating to or deleting from. They just keep their original name.
Therefore, the extra trick is to set the alias to the table's name before applying the scope.
[...]
$criteria=new CDbCriteria();
Alert::model()->alert_id($alert_id)->is_ack(1)->forEntity($this->trackerId)->web()->applyScopes($criteria);
Alert::model()->updateAll(array('is_ack'=>
10),$criteria); ``` So the above code first sets the alias to use with the criteria. It then sets the $criteria. And finally it calls _updateAll()_ to update all the selected records. Making the solution more robust
 
-------------------------------
 

Now that is great, and most developers would stop there. However, the remaining issue with that is that you have to think about using _applyScopes()_ and setting the alias every time. And if you forget it by accident, all your records will be updated with _updateAll()_ (without taking the scopes into account) and you might just break the contents of your database.
[...]
And what is more is that if you forget to assign the alias, you will get an exception !

Automating
 
----------
 

So, as promised, in order to help you update your Gii basemodel, here is the extract of what I put in my basemodel for Gii (I use Awe/AweModel).


```php
/**
[...]
2 0
4 followers
Viewed: 58 707 times
Version: 1.1
Category: How-tos
Written by: le_top
Last updated by: le_top
Created on: Jul 11, 2014
Last updated: 9 years ago
Update Article

Revisions

View all history