2

我想在下拉列表中显示我们所有项目负责人的姓名。

项目负责人只是在公司工作的部分员工。

这是我的表:

project_leaders
,----,----------------,
| id | hr_employee_id |
|----|----------------|
| 1  |  18            |
'----'----------------'

projects
,----,------,-------------------,
| id | name | project_leader_id |
|----|------|-------------------|
| 1  | cake |         1         |
'----'------'-------------------'

hr_employees
,----,------,---------,
| id | name | surname |
|----|------|---------|
| 18 | joe  | dirt    |
'----'------'---------'

我的 ProjectsController 看起来像这样:

public function add() {
    if ($this->request->is('post')) {
        $this->Project->create();
        if ($this->Project->save($this->request->data)) {
            $this->_sendProjectRequestEmail($this->Project->getLastInsertID() );
            $this->Session->setFlash(__('The project has been saved'));
            $this->redirect(array('action' => 'index'));
        } else {
            $this->Session->setFlash(__('The project could not be saved. Please, try again.'));
        }
    }
    $this->set('projectLeaders',$this->Project->ProjectLeader->find('list');
}

这仅返回项目负责人的 id,而不是姓名和姓氏。因此,它返回 1 而不是 Joe Dirt。

我试过 $this->Project->ProjectLeader->HrEmployee->find('list') 但这列出了所有员工。

我也尝试过指定字段,但它返回一个未知字段错误。

我究竟做错了什么?

4

3 回答 3

7
$this->set('projectLeaders',$this->Project->ProjectLeader->find('list'));

这将仅列出表中的记录,project_leaders并且很可能,因为表本身不包含名称/标题字段(蛋糕会自动拾取为displayField),如下所示:

array(
    1 => 1
)

使用适当的查找

要获得有意义的项目负责人列表,您需要确保获得一个连接project_leadershr_employees其中一种方法是使用可包含行为并简单地指定要在列表中使用的字段:

$projectLeaders = $this->Project->ProjectLeader->find('list', array(
    'contain' => array(
        'HrEmployee'
    ),
    'fields' => array(
        'ProjectLeader.id',
        'HrEmployee.name',
    )
));
$this->set(compact('projectLeaders'));

您的数据库结构是否适合您的需求?

拥有一个相当于说“此用户是管理员”的表可能不是最好的主意 - 如果该表project_leaders(仅)是您hr_employees表上的一个布尔字段并project_leader_id指向,则更容易避免数据问题,并为您提供更简单的查询hr_employee表,而不是其他一些数据抽象。

当然我不知道你的整个模式,很可能有一个很好的理由来拥有一个单独的project_leaders表。

或者 - 非规范化

如果您将名称字段添加到project_leaders- 您不需要加入即可知道项目负责人的姓名或任何时髦:

alter table project_leaders add name varchar(255) after id;
update project_leaders set name = (select name from hr_employees where hr_employees.id = hr_employee_id);

通过这种方式,您可以通过一次查询/联接知道谁是相关项目负责人,而无需进行两次联接来获取员工的姓名。

于 2013-03-20T22:00:59.263 回答
0

您忘记定义 displayField:

默认情况是

public $displayField = 'name';

并且仅对于此表蛋糕中现有的“名称”/“标题”字段,它会自动知道您的下拉列表应该作为标签文本获得什么。要使用其他表的字段,请确保传入fieldsfind() 选项:

'fields' => array('Project.id', 'Project.name');

等等,Cake 就会知道:第一个是键,第二个是显示值。

如果您需要下拉列表中的组合/自定义字段/文本,请使用 virtualFields

public $virtualFields = array(
    'full_name' => 'CONCAT(...)'
);

然后将 displayField 设置为此full_name虚拟字段,或者fields如上所述使用。

于 2013-03-20T13:39:15.147 回答
0

您可以在 ProjectLeader 模型中添加一个虚拟字段:

public $virtualFields = array (
'name' => 'SELECT name FROM hr_employees AS Employee WHERE Employee.id = ProjectLeader.employee_id'
);

此外,将此虚拟字段添加为您的 displayField:

public $displayField = 'name';
于 2013-03-20T15:59:49.567 回答