【问题标题】:Getting names to show in dropdown list with cakephp使用 cakephp 获取名称以显示在下拉列表中
【发布时间】:2013-03-20 13:06:49
【问题描述】:

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

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

这是我的桌子:

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') 但列出了所有员工。

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

我做错了什么?

【问题讨论】:

  • 你做错的是使用基于 ActiveRecord 的 ORM 来完成类似的事情。
  • 不要使用getLastInsertID() - 使用$this->ModelName->id。还有,为什么是hr_ 前缀?

标签: php cakephp cakephp-model cakephp-2.2


【解决方案1】:
$this->set('projectLeaders',$this->Project->ProjectLeader->find('list'));

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

array(
    1 => 1
)

使用适当的查找

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

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

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

【讨论】:

  • 您好,关于您的数据库结构是否适合您的需求。 project_leaders 表是必要的,因为一个人可以是多个项目的负责人,但不是所有项目的负责人。假设 joe 是项目 1 2 和 3 的负责人,bob 是项目 4 和 5 的负责人。这是否有助于理解结构?
  • 您关于可包含行为的方法返回未找到字段错误,即使它存在于数据库中。
  • @DarkRanger 如果每个项目只有一个领导者 - 这是项目表中的一个字段(leader_id -> 员工)。如果您在使用可包含行为时遇到错误 - 请参阅可包含行为的文档。
  • 没错,每个项目只有一个领导者,但该领导者只能从可能的领导者列表(project_leaders)中挑选。我已经阅读了文档,但找不到它为什么不起作用。
  • @DarkRanger 我关于数据库结构的 cmets 旨在让您思考,我并不是说这是错误的(您自己可能会得出结论,这取决于其他因素)。但是,在员工中有一个“我是领导者”布尔字段,在项目中有一个 project_leader_id 字段,嗯,更简单。您现在描述的最常见原因是:1)模型文件命名错误-您根本没有加载模型文件-在其中放入明显的​​解析错误,您的应用程序会崩溃吗? 2) 没有加载可包含的行为。除此之外,我建议 irc 频道,cmets 不适合这种帮助。
【解决方案2】:

你忘了定义 displayField:

默认情况是

public $displayField = 'name';

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

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

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

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

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

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

【讨论】:

  • 这不起作用。当我这样做时,它只是说:找不到列:1054 Unknown column 'HrEmployee.name' in 'field list'
  • 确保你还“包含”了那些相关的表(使用 ContainableBehavior)。当然,如果没有连接,这些字段将不可用。您也可以提高递归级别,但这不是一个非常干净的方法。
【解决方案3】:

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

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

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

public $displayField = 'name';

【讨论】:

  • 如果您需要员工的全名,您可以在 SELECT 子句上使用 CONCAT(...)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-24
  • 1970-01-01
  • 2013-09-15
相关资源
最近更新 更多