I’ve noticed that one cannot extract custom fields from a DB into an ActiveRecord if the ActiveRecord class doesn’t have a public property with that specific name. I’d like to be able to use a setter method as well, not just a property.
I can’t link to the code, since this is one of my first posts, so… The problem code is in /tags/1.1.8/framework/db/ar/CActiveRecord.php#1801 and I think that besides property_exists, it would be nice to check for a setter of that specific attribute name.
foreach($attributes as $name=>$value)
{
if(property_exists($record,$name) || method_exists($record,'set'.$name)) // instead of just property_exists
$record->$name=$value;
else if(isset($md->columns[$name]))
$record->_attributes[$name]=$value;
}
or, for increased performance and (slightly) poorer legibility:
foreach($attributes as $name=>$value)
{
if(property_exists($record,$name))
$record->$name=$value;
else if(isset($md->columns[$name]))
$record->_attributes[$name]=$value;
else if(method_exists($record,($method='set'.$name))
$record->$method($value);
}
Here’s a use case:
I’m trying to extract some “special” aggregated fields along with my records from a DB, to alter record ordering. Specifically, i’m trying to get all the users in a table, but the first records should be those without their info (i.e. meta fields) set:
$c = new CDbCriteria;
$c->select = '*, IF((SELECT COUNT(*) FROM user_info WHERE user_id = t.id)=0,1,0) isNew';
$c->order = 'isNew DESC, name ASC';
$users = User::model()->findAll($c);
But I also want to display a label next to each user specifying if he/she is a "new" user.
foreach($users as $user) {
echo $user->isNew ? 'New user' : '';
}
I don’t want to squeeze too much code in the model class, since this is a single use case throughout a rather large application, where the User class is used extensively. Since I only list users in a single page, I’d rather cram that CDbCriteria in the controller, rather than the model.
Any thoughts?