Виртуални полета и псевдоними на модели

Аз съм начинаещ в 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'

Опитах се да приложа „contain“ в CostsCenter в Scholarship, но грешката все още се появява


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


Отговори (1)


Проблемът е, че извършването на намиране с помощта на containable не избира ScholarshipDetail JOIN Scholarship JOIN CostCenter. Ако погледнете изхода за отстраняване на грешки в SQL, ще видите, че първо той получава записите ScholarshipDetail и Scholarship, след това преминава през тях и добавя записите CostCenter към масива с резултати, като прави отделни селекции в таблицата CostCenter. Следователно полетата CostCenter не са налични за използване във виртуалното поле и заявката е неуспешна. Тази връзка помага да се обясни по-добре този капан, който може да бъде задържан.

Ако наистина искате да запазите вашето виртуално поле, не трябва да използвате containable и да настроите заявката използвайки ръчни присъединявания вместо това.

Въпреки това, тъй като често ще имате такъв проблем, тъй като вашето виртуално поле препраща към различни модели, би било по-добре да вместо това създадете реално поле. Опитайте нещо подобно:

  • Създайте поле, наречено код в таблицата със стипендии
  • Създайте функция, напр. updateCode() в модела за стипендии, която формулира кода, като избира правилната информация от различните таблици и след това актуализира кодовото поле в таблицата за стипендии.
  • Извикайте тази функция от контролера след всяко действие, което може да повлияе на кода, напр. когато се редактира запис за стипендия (или обмислете поставянето му в afterSave обратно извикване на модела за стипендия)
person Ella Ryan    schedule 04.07.2013