Delete Many-Many Related Models

Hi there.

In my app I have Category, Post and PostCategory model.

Category:




	public function relations()

	{

		return array(

			'products' => array(self::MANY_MANY, 'Product', 'tbl_product_category(category_id, product_id)'),

		);

	}



Product:


	public function relations()

	{

		return array(

			'categories' => array(self::MANY_MANY, 'Category', 'tbl_product_category(product_id, category_id)'),

		);

	}

ProductCategory:


	public function relations()

	{

		return array(

			'category' => array(self::BELONGS_TO, 'Category', 'category_id'),

			'product' => array(self::BELONGS_TO, 'Product', 'product_id'),

		);

	}

And when deleting one category I want to delete all products in it. This is how I’m trying to do it:


		$transaction=Category::model()->dbConnection->beginTransaction();

		try

		{

			$criteria=new CDbCriteria;

			$criteria->condition='category_id=:category_id';

			$criteria->params=array(':category_id'=>$id);

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

		

			$categories = Category::model()->with('products')->findByPk($id);

			$categories->deleteAll();

						

			$transaction->commit();

		}

		catch(Exception $e)

		{

			$transaction->rollback();

			throw $e;

		}

And I always get exception:

Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails (sale-monster.tbl_product_category, CONSTRAINT tbl_product_category_ibfk_6 FOREIGN KEY (category_id) REFERENCES tbl_category (id) ON DELETE NO ACTION ON UPDATE NO ACTION). The SQL statement executed was: DELETE FROM tbl_category

What am I doing wrong? Should I use "on delete cascade" option to perform this deletion, if so, please help me to do it.

Thanks a lot in advance, Max.

Hi,

as this is a database message (not a Yii message), you should use the cascading delete of your db.

And where exactly I shuld set on cascade delete?

I tried different combinations, like set on delete on product_id, category_id and even both and nothing works properly :(

You can use

FOREIGN KEY … ON DELETE CASCADE (InnoDB only) like Ragua has already mentioned, <— this is the simplest

or Yii triggers, like beforeDelete (notice that deleteAll will not run the triggers),

or consequent delete (delete related then the record itself),

or drop foreign key constraint and do all the cleaning stuff when it’s convenient (for example, by crontab once a day),

or something else.

The choice is yours, and it depends on your task.

Just don’t know where to activate ON CASCADE DELETE to get it work

It’s an option, yes.

Tried, jsut not working for me

Interesting option, thanks a lot for all. Спасибо)

if thats not working as Orey suggested you can use the AR hooks