The Alternative PHP Cache (APC) is commonly used with Yii applications, as it can speed up script running time by a factor of two. Compiled code is kept in shared memory for quick and easy access instead of being compiled each time a script is ran.
The only problem this can bring, is that if you a developing a site and APC is on, you won’t see any changes in your PHP code until APC is flushed.
Today we had a problem where a findAll() with criteria wasn’t bringing back expected results.
Yii appeared to be bringing back some results, but then as we looped through the CActiveRecord objects and attempted to access their relations, it became clear that because we didn’t have all the information we needed, Yii was almost ‘filling in the blanks’ and adding more records into our results – even records that weren’t possible given the original $CDbCriteria object passed into the findAll().
After a bit of head scratching and research, we worked out our query was missing one crucial element – the ‘together’ method. This guy makes sure that all the related tables requested in the ‘with’ method, or in the CDbCriteria are included and used properly:
$criteria = new CDbCriteria;
$criteria->condition = //.... etc
// Be sure to use ->with('joined_tables') ...
// and ->together() to make it all work!
$categories = Category::model()->with('products','products.images')->together()->findAll($criteria);
This gave us our correct array of CActiveRecord objects, with all the correct relations that we were then able to loop through, problem free.
So today I had a need to retrieve and order an array of CActiveRecord objects before looping and printing.
However, I knew I already had the objects in my $model object and the thought occurred that it must be possible to order the relations within this model, rather than perform a new CActiveRecord call with an order clause.
After a bit of reading from the Yii docs (http://www.yiiframework.com/doc/guide/1.1/en/database.arr#dynamic-relational-query-options), I realised that this was indeed possible.
You can perform dynamic relational queries on an existing CActiveRecord object, so in my case – ordering:
// Get a category, which comes with all its relations:
// the 'default' order of products would be:
$products = $category->products;
// But we can pass an array of query options, such as order:
$products = $category->products(array('order' => 'order_column ASC'));
We could also have other query options:
$products = $category->products(array('condition' => 'active=1'));
$products = $category->products(array('condition' => 'product_id IN (1,2,3)'));
// etc, etc...