An object instead of an array

This topic just gave me an idea. Sometimes I have to write such code in my models:




protected function beforeDelete()

{

    if (parent::beforeDelete())

    {

        foreach ($this->someRelation as $model)

            $model->delete();

        return true;

    }

}



Here I manually delete all related models, because for each of them I need before/after delete methods to be called. But what about a more simple solution:




$this->someRelation->delete();



This is HAS_MANY relation and now it returns an object instead of an array (but can be also used as an array).

Same can be done for findAll() methods:




MyModel::model()->findAll($criteria)->delete();



There can be other methods besides delete(). What do you think about it? :)

delete specific records without pk

$criteria=new CDbCriteria;

	$criteria->condition='field1=:field1 AND field2=:field2';


	$criteria->params=array(':field1'=>$field1,':field2' =>$field3 );


	Model_Name::model()->deleteAll($criteria);

I find this very interesting.

Usually, InnoDB does this job for me, BUT there are cases when, beside deleting the actual record from the database, i also need to delete something else (that is not connected to that particular model via innodb relations).

The most common example is:

Say i have a table User and a Post table.

Each user may have n posts, but a post can also have a "main image", which is a file on the server and a column in the database table(not blob, just plain varchar, holding the file path).

Now, using innodb, when deleting a certain user, automatically all his posts are deleted too, but what about the images of the posts ? These will be orphaned on the server.

Even if the post model has before/after delete methods(and in those methods i delete the after mentioned file), these methods won’t be called in this case.

So, i end up with:




foreach($user->posts AS $post)

{

  $post->delete();//to call the before/after delete methods and get rid of the files.

}

$user->delete();



So i think we will need some kind of idea so that if the above scenario applies, the before/after methods of the Post model are called too.

Thoughts ?

I like the idea

findAll and has-many / many-many relations could return a CModelCollection object that extends from ArrayIterator

In extention to Gustavo, the collection class returned could be configurable in the relation? So $someGallery->images could return my own ImageCollection?

Would be cool to write something like this? :)




$gallery->images->addWatermark('watermark.png');



I do exactly this on my custom Yii version, all relations returns a CModelCollection (that is a CModel in with all "fields" are a number-based array index), and the relation can be configured to use a different CModelCollection-descending class. This is a very powerful concept.

For example, a model collection that knows how to save many_many relations, you just add a checkbox list directly to the "groups" field, and it gets the value array and saves on the relation table:




	public function relations()

	{

		return array(

			'groups'=>array(self::MANY_MANY, 'AdminGroup', '{{admin_groups}}(admin_id, admingroup_id)',

				'with'=>'operations',

				'modelCollection'=>array('wobjext.wyii-ext.modelcollection.WManyManyModelCollection')),

		);

	}




Can we have a core developer’s thoughts on this?

Thinking about having a collection object for a long time already but have no final decision on how its API should look like and if we should implement it at all. It certainly can be useful but most of the time there’s no need to use it.

having Yii arrays as silver bullet for any static values is minefield with hi risks in it. Hi coupling possible compatibility issue in future. Is it so hard, create static objects with need parameters for all classes that use static words for config.

Plus side of it will be available and documented all variants of settings and you font have to search ‘showHeader’ parameter name means, or even exists.

pray to Yii2 will have it.

I really like the idea of relation lists being objects, it would also be very cool to be able to do something like:


$model->myHasManyOrManyManyRelation->getDataProvider(); // get an active data provider with the related records

$model->myHasManyOrManyManyRelation->add($otherModel); // add relation from model instance

$model->myHasManyOrManyManyRelation->add(123); // add relation by id

$model->myHasManyOrManyManyRelation->remove(123); // remove relation by id

$model->myHasManyOrManyManyRelation = array(123, 456, $otherModel); // massively assign the relations, replacing existing assignments

$model->myHasOneRelation = 123; // update the foreign key in the appropriate field in row 123 of the remote table

$model->myHasOneRelation = $otherModel; // update the foreign key in the appropriate field of $otherModel

$model->myBelongsToRelation = 123; // set the appropriate foreign key in $model to 123

$model->myBelongsToRelation = $otherModel; // update the appropriate foreign key in $model to the pk of $otherModel

I agree, the idea of a ‘object collection’ class is nice. I often find myself either having to create one to handle my Has_many relations, especially when you for example got multiple attributes each having their own (multiple) values. This gets messy without a decent collection class because of the need to add extended functionality or exceptions.