Виртуальные поля и псевдонимы моделей

Я новичок в cakephp и у меня следующая проблема:

Модель: CostsCenter->Scholarship->ScholarshipsDetail

<сильный>1. Виртуальное поле в модели стипендии:

public $virtualFields = array(
    'code' => "UPPER(CONCAT(SUBSTR(CostsCenter.name, 1, 3), '-',
     Scholarship.selection_year, '-', SUBSTR(Country.name, 1, 3), '-', 
     Postulant.number))");

<сильный>2. Перечислите все в контроллере из ScholarshipsDetail

$scholarships_detail = $this->ScholarshipsDetail->find('all', 
          array('contain' => array('Scholarship' => array('CostsCenter')),
                'conditions' => array('ScholarshipsDetail.scholarship_id' => $scholarship_id)));

Затем мне нужно перечислить ScholarshipsDetail, но у меня ошибка:

Column not found: 1054 Unknown column 'CostsCenter.name' in 'field list'

Я пытался применить «содержать» в CostsCenter через Scholarship, но ошибка все еще появляется


person yagan83    schedule 03.07.2013    source источник


Ответы (1)


Проблема заключается в том, что при поиске с использованием содержимого не выбирается ScholarshipDetail JOIN Scholarship JOIN CostCenter. Если вы посмотрите на выходные данные отладки SQL, вы увидите, что сначала он получает записи ScholarshipDetail и Scholarship, затем перебирает их и добавляет записи CostCenter в массив результатов, выполняя отдельные выборки в таблице CostCenter. Поэтому поля CostCenter недоступны для использования в виртуальном поле, и запрос завершается ошибкой. Эта ссылка помогает лучше объяснить эту ловушку.

Если вы действительно хотите сохранить свое виртуальное поле, вам не следует использовать вмещаемый и настраивать запрос с помощью объединения вручную вместо.

Однако, поскольку у вас часто будут возникать проблемы такого рода, поскольку ваше виртуальное поле ссылается на разные модели, было бы лучше создать вместо этого реальное поле. Попробуйте что-то вроде этого:

  • Создайте поле с кодом в таблице стипендий.
  • Создайте функцию, например updateCode() в модели стипендий, которая формулирует код, выбирая правильную информацию из различных таблиц, а затем обновляет поле кода в таблице стипендий.
  • Вызовите эту функцию из контроллера после любого действия, которое может повлиять на код, например, когда редактируется запись о стипендии (или рассмотрите возможность помещения ее в обратный вызов afterSave модели Scholarship)
person Ella Ryan    schedule 04.07.2013