У меня есть две ситуации, когда выполняются два похожих запроса, и в одной ситуации код для виртуального поля связанной модели не генерируется в sql запрос запроса и, следовательно, не найден.Виртуальное поле ассоциированной модели в похожих запросах, но иногда не встраивается в sql-запрос
В базе данных: * Два мастер-таблица (hospitals
и hotels
) * Один ссылочной таблица contacts
* Мастер таблица имеет различные поля, указывающие на контактной таблицу. Для больниц, например. a director_contact_id
и a janitor_contact_id
. Для гостиниц a director_contact_id
и concierge_contact_id
.
В CakePHP * The Hospital
модели имеет два belongsTo отношения DirectorContact
и JanitorContact
* The Hotel
модель имеет два belongsTo отношение DirectorContact
и ConciergeContact
* контакты имеют виртуальное поле full_name
, нечто вроде CONCAT(…)
В HospitalController , когда мне нужна одна из данных контакта, привязанных к данным больницы, я могу сделать:
$contain = array();
…
$contain['DirectorContact'] = array('fields' => array('id','full_name'));
…
$this->Hospital->find('all', array(
…
'contain' => $contain,
…
));
сгенерированный код SQL содержит
CONCAT(…) AS DirectorContact__full_name
Однако, тот же не работает в HotelController. Там я также делаю:
$contain['DirectorContact'] = array('fields' => array('id','full_name'));
И если я
debug($this->Hotel->DirectorContact->virtualFields);
Я получаю
array(
'full_name' => 'CONCAT(…)'
)
Но когда я запускаю действие я получаю сообщение об ошибке SQL произнося поле full_name
неизвестно. И я вижу, что в запросе sql, который сгенерирован, отсутствует CONCAT(…) AS DirectorContact__full_name
.
В обоих случаях контактная таблица ссылается более одного раза, по меньшей мере, существуют ассоциации с различными псевдонимами. Поэтому я не уверен, почему CakePHP генерирует правильный запрос в одном случае, но не в другом.
Конечно, фразы поиска более сложны, больше содержит, объединяет и поля, чем я указал здесь.
Вопрос 1: Кто-нибудь знает, что может заставить CakePHP отказаться от генерации кода для виртуального поля связанной модели?
Я читал, что сдерживаемое поведение немного деликатно и что в некоторых ситуациях лучше использовать объединения.
Так что в том случае, когда виртуальное поле не работало, я использовал объединения вместо того, чтобы содержать.Тем не менее, виртуальное поле не генерируется, так что я сделал это явно для обоих assiciations:
$fields[] = 'DirectorContact.id';
$fields[] = 'CONCAT(…) AS `DirectorContact__name_or_company`';
$fields[] = 'ConciergeContact.id';
$fields[] = 'CONCAT(…) AS `ConciergeContact__name_or_company`';
Если я отлаживать результат запроса:
array(
'Hotel' => array(
'id' => '123',
),
'DirectorContact' => array(
'id' => '456',
'name_or_company' => 'Some name'
),
(int) 0 => array(
'ConciergeContact__name_or_company' => 'Some other name',
),
'ConciergeContact' => array(
'id' => '789'
),
)
Таким образом, для первой ассоциации с Automagic работы и CakePHP напишите содержимое виртуального поля DirectorContact__name_or_company
в часть ассоциативного массива DirectorContact
, но другой get помещается в «общую» часть для вычисленных полей, на которые указывает ключ 0.
Но что еще больше в teresting: если я поменять порядок ссылок модели в определении поля для
$fields[] = 'ConciergeContact.id';
$fields[] = 'CONCAT(…) AS `ConciergeContact__name_or_company`';
$fields[] = 'DirectorContact.id';
$fields[] = 'CONCAT(…) AS `DirectorContact__name_or_company`';
результат
array(
'Hotel' => array(
'id' => '123',
),
'ConciergeContact' => array(
'id' => '789'
),
(int) 0 => array(
'ConciergeContact__name_or_company' => 'Some other name',
'DirectorContact__name_or_company' => 'Some name',
),
'DirectorContact' => array(
'id' => '456',
),
)
Так что теперь Automagic больше не работает на всех, и как виртуальные поля wqritten в общая часть.
Вопрос 2: Кто-нибудь знает причину этого и как заставить автомат CakePHP работать во всех случаях?
(с использованием версии 2.4.3)