Yii Framework Forum: Many To Many Relationship With Same Model - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Many To Many Relationship With Same Model Rate Topic: ***** 1 Votes

#1 User is offline   Prashanth S 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 6
  • Joined: 27-December 12

Posted 30 December 2012 - 11:54 PM

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
0

#2 User is offline   softark 

  • Keep It Simple
  • Yii
  • Group: Moderators
  • Posts: 2,085
  • Joined: 16-February 11
  • Location:Japan

Posted 31 December 2012 - 12:25 AM

Hi Prashanth,

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";

0

#3 User is offline   Prashanth S 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 6
  • Joined: 27-December 12

Posted 31 December 2012 - 02:58 AM

Hi softark,

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.

0

#4 User is offline   softark 

  • Keep It Simple
  • Yii
  • Group: Moderators
  • Posts: 2,085
  • Joined: 16-February 11
  • Location:Japan

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.
0

#5 User is offline   Prashanth S 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 6
  • Joined: 27-December 12

Posted 31 December 2012 - 04:33 AM

View Postsoftark, 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.



Thanks dude. Can you give me a sample code to save a Employee record along with the relationship manually without that extension.
0

#6 User is offline   softark 

  • Keep It Simple
  • Yii
  • Group: Moderators
  • Posts: 2,085
  • Joined: 16-February 11
  • Location:Japan

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.

$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();
    }
}

0

#7 User is offline   Prashanth S 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 6
  • Joined: 27-December 12

Posted 31 December 2012 - 05:12 AM

View Postsoftark, 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.

$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']) . "')");

0

#8 User is offline   Prashanth S 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 6
  • Joined: 27-December 12

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.

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.


0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users