saving many many relationships

Hi everyone,

I just started to investiage the Yii framework since I'm looking for alternatives to CakePHP. The main reason why I want to stop using cake is because of its php4 implementation of ORM and all the restrictions that come with it.

The first problem I encountered when using Yii is that I can't figure out how to efficiently save many many and has many relationships.

If I have a form with multiple checkboxes which will give me the IDs of the relationship items - How do I save them to the database?

The active record section of the guide doesn't say how this is done and I can't seem to figure it out.

thanks for your help


There is no Active Record way to save MANY_MANY relations, it must be done manually.  The method I use is to create a model for the join table.  For example:

Here are three tables:



CompanyPerson (I always use alphabetical order to save confusion) - this is the join table

Each of the tables has a model.  When a person is being created, in the PersonController I would use the following code to create MANY_MANY relations with companies.

// ignoring XSS filtering

// $_POST['companies'] is an array of Company IDs

foreach ($_POST['companies'] as $companyId) 


  $relationship = new CompanyPerson;

  $relationship->personId = $person->personId; // from Person model

  $relationship->companyId = $companyId; // from $_POST form submission

  $relationship->save(FALSE); // No need to validate


That's what I do.  It's far from perfect - I'll be interested to hear what others' approaches are. 

Hi Alex

thank you for your reply. I know that you would need a join table.

I was hoping that there would be a way built in to Yii how this could be done without having to write a for loop like the one that you described.

As I have mentioned in my previous post I've been working a lot with CakePHP and with cake it is possible to just pass an array of persons to the company object when it is saved.

I believe that in Rails you can do something similar.

I'm hoping that there is a different way of doing this.


Currently there is no better way to do this in Yii, I hope this will be solved in an upcoming release soon. Still I also decided to use Yii instead of Cake, the code seems better and its build for php5.

I found this code in the blog demo application

	protected function afterSave()



			$this->dbConnection->createCommand('DELETE FROM PostTag WHERE postId='.$this->id)->execute();



			foreach($this->getTagArray() as $name)




					$tag=new Tag(array('name'=>$name));



				$this->dbConnection->createCommand("INSERT INTO PostTag (postId, tagId) VALUES ({$this->id},{$tag->id})")->execute();




It should be possible to write a behaviour that takes a similar approach and takes care of the job.

I don't have time to look into it some more but in a couple weeks I'll probably get around to trying to write something along these lines. Having this in the core would be great of course


I agree that Yii seems to be better built than CakePHP. I was getting really annoyed by Cake's ORM and how it relies on arrays instead of objects. I very much prefer writing $this->attribute over having to write $this->data['Modelname']['attribute']

In some areas Yii still falls short of Cake since cake has been around longer.

I hope this is gonna change in the future