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