Collection of models into array conversion.


till today i was using this type of expressions when needed:

$arr = CHtml::listData(MyModel::model()->findAll(), 'id', 'id');

which basically gives me an array with ids needed (maybe with conditions). After that i used that array to build JSON responses or sometimes to run another database search like this:


Today i’ve found it is incorrect. If suddenly first expression (CHtml::listData(…)) return an array with just 1 value, i.e. array(2=>2), then second expression will run a weird SQL query instead of … IN … condition it will create WHERE parent_id IS NULL… What?! Ok, i go to sources and find out that class CDbCommandBuilder contains a method createInCondition which has following code at line 663:

return $prefix.$column->rawName.($values[0]===null?' IS NULL':'='.$values[0]);

This means that when an array, that i provide to findAllByAttributes as values, consists of just 1 value and has an index key NOT 0, i will get that weird WHERE condition.

Now, i thought it’s a bug and before petitioning it i searched for a while and found this:

Basically Qiang says it’s not a bug, but bad usage of createInCondition method. Wow. So, my question is how do you do it right? How should i convert a collection of models MyModel::model()->findAll() into an array of values (not all fields, but just one) to pass it to AR?

you finally need an array , why not use the DAO queryColumn method

if you get the final array from some methods of CActiveRecord, you waste too much both time and space .you need an direct way to get your result ::)

you see if you need an array from some ActiveRecords you will have to get these ars first (findAllByxx())

and then use foreach/for to loop the array of ars:

$ars = SomeModelClass::model()->findAllByXX();

foreach($ars as $ar) {

$results[] = $ar->someAttr;


//here you get it

i don’t think this is a effective way :D

I don’t like to mess AR and raw DAO. Basically AR serves perfect for everything i need.

For example, i use complicated multilanguage AR, which is integrated into my AR class with relations and behaviors. If i start mess DAO with AR around it will be huge code matrix.

Almost all requests are cached, so the performance isn’t really an issue.

And obviously i won’t write foreach at every place where i need an array of values from models collection.

For the moment I wrote a helper method similar to CHtml::listData which is able to make non-indexed arrays.

I’m still pretty sure that use of $values[0] inside framework code is bad mannered and consider it as bug. It’s very strange Qiang doesn’t want to change it.