Yii - 多个部门

时间:2013-08-06 15:40:52

标签: yii models relation

Yii的新手,虽然不是PHP的新手。在Larry Ullman为Yii提供的教程中,我设置了一个Employees MySQL表和一个Department表。 Employee表有一个专栏departmentId,它关联链接到Department以获取Id并获取该部门的名称。

但这是我的问题。我公司的员工可以在多个部门(例如客户服务和技术支持)中浮动。我当前的Yii设置似乎只设置为获取单个部门。我怎么能这样做,以便我可以输入一个员工的多个部门ID(用逗号或|之类的东西分隔),当Yii拉下那个员工时,它会打破那些并列出所有部门雇员?

我知道这是过于笼统的界限,所以我在下面发布了一些代码,其中包含模型中Employee的关系:

    public function relations()
{
    // NOTE: you may need to adjust the relation name and the related
    // class name for the relations automatically generated below.
    return array(
        'department' => array(self::Belongs_To, 'Department', 'departmentId'),
    );
}

2 个答案:

答案 0 :(得分:3)

听起来你需要一个n:m的关系:所以一个员工可以分配到很多部门,一个部门有很多员工。 您需要的是一个所谓的数据透视表,用于将员工连接到一个或多个部门,如下所示:

tbl_employee(身份证,姓名,年龄等) tbl_employee_department(employee_id,department_id) tbl_department(id,name等)

现在您的员工关系如下:

public function relations()
{
    return array(
        'departments' => array(self::MANY_MANY, 'Department', 'tbl_employee_department(employee_id, department_id)'),
    );
}

你的部门关系看起来像这样:

public function relations()
{
    return array(
        'employees' => array(self::MANY_MANY, 'Employee', 'tbl_employee_department(employee_id, department_id)'),
    );
}

现在$ employee->部门将返回一系列部门模型。但是你想要的表单是一个部门ID数组,所以你必须在你的员工模型中这样做

public $departmentIds=array();

public function afterFind()
{
    if(!empty($this->departments)) {
        foreach($this->departments as $id=>$department)
            $this->departmentIds[]=$department->id;
    }
    parent::afterFind();
}

public function afterSave()
{
    $tx = Yii::app()->db->beginTransaction();
    try {
        //delete all connections from this employee to any department first
        $command = Yii::app()->db->createCommand();
        $command->delete('tbl_employee_department', 'employee_id=:id', array(':id'=>$this->id));
        //now reconnect the employee to the departments in the departmentIds array
        foreach($this->departmentsIds as $id) {
            $command = Yii::app()->db->createCommand();
            $command->insert('tbl_employee_department', array(
                'employee_id' => $this->id,
                'department_id'=> (int)$id
            ));
        } 
        $tx->commit();
    } catch (Exception $e) {
        $tx->rollback();
        throw new CException('Something bad happend. Cancelled transaction and rolled back data! '.$e->getMessage());
    }

    parent::afterSave();
}

此代码从数据库中提取部门,并在从数据库中获取员工模型后立即将其ID存储在$ departmentIds数组中(通过Employee :: model() - > find()等)。当您调用$ employee-> save()并且保存过程成功时,将调用afterSave方法。然后,它将启动一个事务,删除该员工与其分配给的所有部门之间的所有连接,然后添加存储在departmentIds数组中的所有部门。

如果你想通过$ model-> setAttributes()设置这个字段,你必须将它声明为安全(因此Yii允许它被批量分配),方法是将它放在你的员工规则中

public function rules()
{
    return array(
      //...all the other rules...
      array('departmentIds', 'safe'),
    );

}

我知道,看起来很复杂,但它应该给你一个想法。剩下的唯一问题是通过表单设置departmentIds数组的id,但你可以爆炸一个texfield的字符串来做那个等等。这应该不是那么难我猜

答案 1 :(得分:0)

您不必使用“属于”关系类型,而是必须为模型使用“多个”关系。有关模型关系的更多信息here

'许多'关系要求您添加另一个表来存储这些关系,如下所示:

Employees_Departments:id | employee_id |部门标识

然后,您可以从employee表中删除department_id列。

我希望这有帮助!