CakePHP удаляет другие записи HABTM в saveAll - PullRequest
1 голос
/ 03 июля 2011

У меня есть две модели, связанные с HABTM: отсутствие и пользователи.Для контекста, пользователи подают заявки на отсутствие (и, соответственно, пользователь имеет псевдоним для заявителя, а отсутствие - для отсутствия).Я пытаюсь создать функции контроллера для 'apply' и 'retract', которые добавили бы запись HABTM и удалили запись HABTM соответственно.Я получил код до такой степени, что он будет сохранять одну запись, но не более.Прямо сейчас мой код контроллера для 'apply' жестко запрограммирован, чтобы добавить пару записей, но он добавляет только последнюю запрошенную.Вот мой код контроллера:

function apply($id = null) {
            if (!$id) {
                    $this->Session->setFlash(__('Invalid id for absence', true));
                    $this->redirect(array('action'=>'index'));
            }

            $this->Absence->recursive = 1;
            $user = $this->Session->read('User');
            $absence = $this->Absence->read(null, $id);
            $data = array(
                    array(
                            'Applicant' => array('id' => 1),
                            'Absence' => array('id' => 4)
                    ),
                    array(
                            'Applicant' => array('id' => 2),
                            'Absence' => array('id' => 4)
                    )
            );

            //$data = array_unique($data);
            if ($this->Absence->saveAll($data)) {
                    $this->Session->setFlash('Application was successful');
            } else {
                    $this->Session->setFlash('Application failed');
            }
            $this->set(compact('data'));
    }

Я вижу обе записи в $ data, обрабатываемые в отладочных запросах, но по какой-то причине одна из них удалена.Кто-нибудь знает почему?Вот некоторые запросы, выполняемые этим кодом контроллера (обратите внимание на 19, 25 и 26):

11  START TRANSACTION       0       0
12  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
13  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
14  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
15  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
16  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
17  UPDATE `absences` SET `id` = 4, `modified` = '2011-07-03 00:28:39' WHERE `absences`.`id` = 4        1       0
18  SELECT `AbsencesUser`.`user_id` FROM `absences_users` AS `AbsencesUser` WHERE `AbsencesUser`.`absence_id` = 4       0   0   0
19  INSERT INTO `absences_users` (`absence_id`,`user_id`) VALUES (4,1)      1       0
20  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
21  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
22  SELECT COUNT(*) AS `count` FROM `absences` AS `Absence` WHERE `Absence`.`id` = 4        1   1   0
23  UPDATE `absences` SET `id` = 4, `modified` = '2011-07-03 00:28:39' WHERE `absences`.`id` = 4        0       0
24  SELECT `AbsencesUser`.`user_id` FROM `absences_users` AS `AbsencesUser` WHERE `AbsencesUser`.`absence_id` = 4       1   1   0
25  DELETE `AbsencesUser` FROM `absences_users` AS `AbsencesUser` WHERE `AbsencesUser`.`absence_id` = 4 AND `AbsencesUser`.`user_id` = (1)          1       1
26  INSERT INTO `absences_users` (`absence_id`,`user_id`) VALUES (4,2)      1       0
27  COMMIT      0       123

Ответы [ 2 ]

1 голос
/ 03 июля 2011

Я вижу, как обе записи в $ data обрабатываются в отладочных запросах, но по какой-то причине одна из них удаляется.Кто-нибудь знает почему?

Конечно, потому что это стандартное поведение Cake. Прочтите этот раздел о сохранении данных с помощью HABTM.

В этом разделе кратко рассказывается о создании отдельной модели для таблицы соединений, но я не думаю, что она достаточно справедлива, объясняя, что именнозначит или как ты это делаешь. Я не предполагаю, что это должен быть ваш подход, вам следует изучить информацию и принять решение на основе вашего приложения! Схема данных, безусловно, является одним из наиболее важных аспектов.

Я не знаком с Ruby on Rails, но по сути мы хотим продублировать RoR has_many :through модель связи.Короче говоря, мы хотим иметь возможность работать с таблицей HABTM join точно так же, как и с любой другой моделью.

Итак, мы бы настроили наши новые ассоциации моделей следующим образом:

Ваша Absence модель ...

class Absence extends AppModel {

    public $belongsTo = array('AbsentUser');
    ...

Ваша User модель ...

class User extends AppModel {
    public $belongsTo = array('AbsentUser');
    ...

Ваша новая AbsentUser модель ...

class AbsentUser extends AppModel {
    public $hasMany = array('Absence', 'User');
    ...

Теперь вы можете использовать AbsentUser в качестве своей собственной модели, что позволяет вам обходить поведение HABTM по умолчанию в Cake.Кроме того, он позволяет вам легко расширять данные AbsentUser, чтобы включить дополнительные поля, если вы того пожелаете.Например, вы можете хранить конкретную информацию об определенном отсутствии.

Я также настоятельно рекомендую убедиться, что у вас есть толстые модели и контроллеры скинни. .Ты будешь любить себя позже, если ты это сделаешь.

0 голосов
/ 18 июня 2014

Начиная с версии 2.1, теперь вы можете установить уникальное значение keepExisting , чтобы обойти потерю дополнительных данных во время операции сохранения.

 var $hasAndBelongsToMany = array(
        'User'  => array(
            'unique' => 'keepExisting',
            ),
    );
...