Данные HABTM повреждены во время __saveMulti ()? - PullRequest
0 голосов
/ 06 марта 2010

Я использую Cake 1.2.6, и вчера вечером я заметил, что отношения HABTM не сохранялись при отправке формы.

У меня есть отношение HABTM между Committee и Volunteer. Первичный ключ для Volunteer - это UUID, а первичный ключ для Committee - это читаемая человеком строка (например, BOARDOFDIRECTORS, FAIRCOMMITTEE, FAIRASSOCIATES и т. Д.). У меня есть форма для создания / редактирования добровольцев, и эта форма включает в себя поле выбора, параметры которого точно соответствуют вашим ожиданиям, и в них содержатся параметры, возвращаемые методом Cake find( 'list' ). Хотя я не могу придумать причину, по которой это имело бы значение, для добровольца может быть выбран только один комитет (HABTM предназначен для ожидаемых будущих потребностей).

Первоначальные результаты показывают, что выбор опции BOARDOFDIRECTORS работает, как и ожидалось, но другие - нет. Отслеживание выполнения через основной код приводит меня к Model->__saveMulti(), где в Строка 1393 этот код выполняется:

 $data[$this->hasAndBelongsToMany[$assoc]['foreignKey']] = $id;

Если я дам дамп $data перед этим кодом, вывод будет FAIRASSOCIATES . Сразу после этого его значение равно 4AIRASSOCIATES . Кажется безопасным предположить, что именно поэтому отношения не сохраняются, но я не выяснил, почему данные изменяются на этом этапе выполнения.

Кто-нибудь еще видел это? Я пропустил какой-то критический кусок? Насколько мне известно, это работало нормально в v1.2.1 (я обновил неделю назад или около того).

UPDATE

Первый бит кажущейся странности, который я вижу, состоит в том, что, хотя мой $row является строкой, условие в Строка 1366 оценивается как true, поэтому я перехожу кодовый блок. Если мои данные являются строкой, как они могут иметь значение члена?

UPDATE

У меня явно есть кое-какие мысли, но вот суть. Если я сбрасываю записи журнала непосредственно перед и сразу после Строка 1394 примерно так:

$this->log( 'Setting ' . $data . '[' . $this->hasAndBelongsToMany[$assoc]['foreignKey'] . '] = ' . $id, LOG_DEBUG );

$data[$this->hasAndBelongsToMany[$assoc]['foreignKey']] = $id;

$this->log( 'Creating ' . json_encode( $data ) . ' on ' . $join, LOG_DEBUG );

Соответствующий вывод:

2010-03-05 18:57:08 Debug: Setting FAIRASSOCIATES[volunteer_id] = 4b78717f-8ad4-4671-b81c-4e8745591fb4
2010-03-05 18:57:08 Debug: Creating "4AIRASSOCIATES" on CommitteesVolunteer

Возможные проблемы:

  1. Я не уверен, как / почему Cake пытается установить член volunteer_id в строку
  2. "FAIRASSOCIATES" - это идентификатор комитета, в который входит добровольец, а не модель какого-либо рода, поэтому я вообще не понимаю значения FAIRASSOCIATES[volunteer_id].
  3. Я понятия не имею, как или почему значение $data превращается в 4AIRASSOCIATES этой одной строкой кода.

Ответы [ 2 ]

1 голос
/ 13 марта 2010

Я написал небольшое исправление, и оно в ТЕСТИРОВАНИИ (атм работает): оно переопределяет обнаружение uuid (глупо, если просто спрашивает, имеют ли данные длину 16 или 32), и предполагает, что это действительный идентификатор, если это строка или число для введенных данных.

просто добавьте функцию (скопируйте всю функцию):

функция __saveMulti ($ join, $ id)

От lib.bb model.php до app_model.php вашего приложения

Затем замените IF ранее в строке model.php 1355:

if ((is_string ($ row) && (strlen ($ row)) == 36 || strlen ($ row) == 16)) || is_numeric ($ row)) {

СЕЙЧАС ваш app_model.php для этого (не редактируйте model.php вашей библиотеки, сделайте это в своем app_model.php):

if ((is_string ($ row) && ((strlen ($ row) == 36 || strlen ($ row) == 16) ||! $ This -> {$ assoc} -> autoPrimaryKey)) | | (is_numeric ($ row))) {

затем в вашем app_model.php добавьте эту переменную:

    var $autoPrimaryKey = true;

и в моделях, для которых требуется, чтобы это поведение добавляло ту же переменную, но в false, она будет предполагать, что модель не имеет автоматически сгенерированного UUID для HABTM, и устраняет проблему

    var $autoPrimaryKey = false;

Повторюсь, это просто исправление в тестировании, оно решило проблему для меня, любой вопрос, который у вас есть, отправьте его на мою почту zydriel AT gmail.com

0 голосов
/ 07 марта 2010

Похоже, моя проблема вызвана чем-то необычным. Для справочных таблиц, значения которых меняются редко (и у них нет планов делать это через приложение), мне нравится, чтобы значения PK были удобочитаемыми для человека. Это позволяет мне просматривать данные непосредственно в базе данных и читать соответствующие записи. В этом случае я могу просмотреть запись Volunteer и, не требуя какого-либо соединения, увидеть, что он / она находится в Committee с именем FAIRCOMMITTEE. Вид удобен при просмотре данных вне приложения.

В этом случае одно из моих значений 3 Committee оказалось длиной 16 символов - длина CakePHP, интерпретируемая как UUID, - поэтому он вел себя правильно. Остальные не 16 символов и не ведут себя правильно.

Неудачное условие: Строка 1355 . Я ввел билет , чтобы посмотреть, есть ли место для улучшения интеллекта обнаружения UUID.

...