Hi,
I'm a newbie in Yii framework. I just got stuck in a relationship problem please help me to solve it. Problem is described below.
Relationship is actually with the same model. I have an Employee model. Usually a company will have only one manager per employee. But in this case there may be more than one manager per employee. He also will be another Employee only who may or may not have one or more managers again.
So I need to define Many-to-Many relationship for Employee model with itself. How can I achieve that. I googled a lot, but didn't find any proper solution.
Hope you understand the problem. Please help me ASAP.
Thank you
Prashanth
Page 1 of 1
Many To Many Relationship With Same Model
#2
Posted 31 December 2012 - 12:25 AM
Hi Prashanth,
I changed 'Employee' to 'Person' in order to clarify the wording, because employee can have many employees.
The point is that you can create a bridge table that defines the relations between 2 persons: one is employee and the other is manager. And the Person model has 2 relations: employees and managers.
By doing this you can retrieve the managers and the employees of one person.
person id name employee_manager employee_id ... FK to person.id manager_id ... FK to person.id // Person.php 'managers' => array(self::MANY_MANY, 'Person', 'employee_manager(employee_id, manager_id)'), 'employees' => array(self::MANY_MANY, 'Person', 'employee_manager(manager_id, employee_id)'),
I changed 'Employee' to 'Person' in order to clarify the wording, because employee can have many employees.
The point is that you can create a bridge table that defines the relations between 2 persons: one is employee and the other is manager. And the Person model has 2 relations: employees and managers.
By doing this you can retrieve the managers and the employees of one person.
$person = Person::model()->findByPk($id); foreach($person->managers as $manager) echo $person->name . " has manager named " . $manager->name . "\n"; foreach($person->employees as $employee) echo $person->name . " has employee named " . $employee->name . "\n";
#3
Posted 31 December 2012 - 02:58 AM
Hi softark,
Below given is my implementation. Can you please check it and confirm.
With this situation, I was trying to create a new employee where multi select dropdownlist provides option to select managers. in actionCreate i am trying to save the employee with following code (i am using CAdvancedArBehavior extension) and
that creates an error
Below given is my implementation. Can you please check it and confirm.
employee id name .... subordinate_manager subordinate_id manager_id // Employee.php 'managers' => array(self::MANY_MANY, 'Employee', 'subordinate_manager(subordinate_id, manager_id)'), 'subordinates' => array(self::MANY_MANY, 'Employee', 'subordinate_manager(manager_id, subordinate_id)')
With this situation, I was trying to create a new employee where multi select dropdownlist provides option to select managers. in actionCreate i am trying to save the employee with following code (i am using CAdvancedArBehavior extension) and
$model->attributes=$_POST['Employee']; $model->managers = Employee::model()->findAll("`Id` IN ('" . implode("','", $_POST['Employee']['managers']) . "')"); if($model->save()) $this->redirect(array('view','id'=>$model->Id));
that creates an error
Property "Employee.manager_id" is not defined.
#4
Posted 31 December 2012 - 04:25 AM
I'm sorry, I'm not familiar with that extension and can not help you on it.
But according to the following comment which is on the extension's page, it has a bug in saving MANY_MANY relation.
http://www.yiiframew...rbehavior#c6548
The comment was posted on 2012/01/17, and the extension was uploaded on 2011/5/25. So I think the bug is still there.
But according to the following comment which is on the extension's page, it has a bug in saving MANY_MANY relation.
http://www.yiiframew...rbehavior#c6548
The comment was posted on 2012/01/17, and the extension was uploaded on 2011/5/25. So I think the bug is still there.
#5
Posted 31 December 2012 - 04:33 AM
softark, on 31 December 2012 - 04:25 AM, said:
I'm sorry, I'm not familiar with that extension and can not help you on it.
But according to the following comment which is on the extension's page, it has a bug in saving MANY_MANY relation.
http://www.yiiframew...rbehavior#c6548
The comment was posted on 2012/01/17, and the extension was uploaded on 2011/5/25. So I think the bug is still there.
But according to the following comment which is on the extension's page, it has a bug in saving MANY_MANY relation.
http://www.yiiframew...rbehavior#c6548
The comment was posted on 2012/01/17, and the extension was uploaded on 2011/5/25. So I think the bug is still there.
Thanks dude. Can you give me a sample code to save a Employee record along with the relationship manually without that extension.
#6
Posted 31 December 2012 - 04:50 AM
Well, it's boring simple.
1. Create a CActiveRecord class for subordinate_manager.
2. Manually set employee_id and manager_id to an instance of SubordinateManager objects and save.
1. Create a CActiveRecord class for subordinate_manager.
2. Manually set employee_id and manager_id to an instance of SubordinateManager objects and save.
$model->attributes=$_POST['Employee']; if($model->save()) { foreach($_POST['Employee']['managers'] as $manager_id) { $link = new SubordinateManager(); $link->subordinate_id = $model->id; $link->manager_id = $manager_id; $link->save(); } }
#7
Posted 31 December 2012 - 05:12 AM
softark, on 31 December 2012 - 04:50 AM, said:
Well, it's boring simple.
1. Create a CActiveRecord class for subordinate_manager.
2. Manually set employee_id and manager_id to an instance of SubordinateManager objects and save.
1. Create a CActiveRecord class for subordinate_manager.
2. Manually set employee_id and manager_id to an instance of SubordinateManager objects and save.
$model->attributes=$_POST['Employee']; if($model->save()) { foreach($_POST['Employee']['managers'] as $manager_id) { $link = new SubordinateManager(); $link->subordinate_id = $model->id; $link->manager_id = $manager_id; $link->save(); } }
It needs an extra class for SubordinateManager. And my problem is fixed within the bug report (the link you gave) the reported guy has given its fix too. I applied the fix and now its perfectly fine. subordinate_manager entries are automatically added when i add the following line before saving the Employee object.
$model->managers = Employee::model()->findAll("`Id` IN ('" . implode("','", $_POST['Employee']['managers']) . "')");
#8
Posted 31 December 2012 - 05:27 AM
I have copied the fix given by the bug reporter so that it may be useful for someone in future.
This is the trouble spot in writeRelation():
It works when I change it to this:
This should let you have the foreign key column names in the relation table be different from the primary key in the main tables.
Quote
This is the trouble spot in writeRelation():
foreach((array)$this->owner->$key as $foreignobject) { if(!is_numeric($foreignobject) && is_object($foreignobject)) $foreignobject = $foreignobject->{$foreignobject->$relation['m2mForeignField']}; $this->execute($this->makeManyManyInsertCommand($relation, $foreignobject)); }
It works when I change it to this:
foreach((array)$this->owner->$key as $foreignobject) { if(!is_numeric($foreignobject) && is_object($foreignobject)) { $pk = $foreignobject->tableSchema->primaryKey; // get the primary key name $foreignobject = $foreignobject->{$pk}; // NOW get the primary key } $this->execute($this->makeManyManyInsertCommand($relation, $foreignobject)); }
This should let you have the foreign key column names in the relation table be different from the primary key in the main tables.
Share this topic:
Page 1 of 1