Получение имен для отображения в выпадающем списке с помощью cakephp

Я хочу показать имена всех наших лидеров проекта в выпадающем списке.

Руководители проекта – это лишь некоторые из сотрудников, работающих в компании.

Вот мои таблицы:

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 | '----'------'---------' 

Мой ProjectController выглядит так:

 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'); } 

Это возвращает идентификатор лидеров проекта, а не имя и фамилию. Поэтому вместо Joe Dirt он возвращает 1.

Я попытался сделать $ this-> Project-> ProjectLeader-> HrEmployee-> find ('list'), но в нем перечислены все сотрудники.

Я также попытался указать поля, но он возвращает неизвестную ошибку поля.

Что я делаю не так?

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

Это будет просто перечислять записи из таблицы project_leaders и, скорее всего, поскольку таблица сама по себе не содержит поля имени / названия (который торт автоматически выбирает как displayField ) displayField так:

 array( 1 => 1 ) 

Используйте соответствующую находку

Чтобы получить значимый список лидеров проекта, вам необходимо обеспечить соединение между project_leaders и hr_employees одним из способов сделать это с помощью сдерживаемого поведения и просто указать, какие поля использовать в списке:

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

Является ли ваша структура db подходящей для ваших нужд?

Наличие таблицы, эквивалентной тому, что «этот пользователь является администратором», может и не быть лучшей идеей – было бы легче избежать проблем с данными и дать вам более простые запросы, если таблица 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); 

Таким образом, вы можете знать, кто является соответствующим проектом с одним запросом / объединением, вместо того, чтобы делать два объединения, чтобы получить имя сотрудника.

Вы забыли определить displayField:

Случай по умолчанию

 public $displayField = 'name'; 

И только для существующего поля «имя» / «название» в этой таблице торт автоматически узнает, что ваши выпадающие списки должны получить как текст ярлыка. Чтобы использовать поля других таблиц, убедитесь, что вы передаете fields в параметрах find ():

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

и т. д. Торт тогда будет знать: первый – это ключ, а второй – отображаемое значение.

Если вам нужны комбинированные / настраиваемые поля / тексты в выпадающих меню, используйте virtualFields

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

и установите для параметра displayField это виртуальное поле full_name или используйте fields как описано выше.

Вы можете добавить виртуальное поле в свою модель ProjectLeader:

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

Кроме того, добавьте это виртуальное поле в свой экран displayField:

 public $displayField = 'name';