2011-01-24 2 views
3

У меня есть относительно простые записи модель с помощью всего пять полей:Cakephp beforeSave не сохраняет новые данные при использовании saveAll?

  1. Ид
  2. типа (что типа данных этой записи)
  3. количества (сколько любого типа он есть)
  4. блока (блок типа)
  5. актуальных (datettime, когда эта запись была введена)
  6. идентификатор_пользователя (идентификатор пользователя, который входит

Итак, ничего необычного. Теперь в одной форме может быть несколько записей (как уже существующих, так и новых), форма расширена через вызовы ajax.

Когда я отправить форму $this->data выглядит следующим образом:

Array 
(
    [Entry] => Array 
     (
      [date] => 2011-01-07 
      [0] => Array 
       (
        [id] => 1 
        [type] => Eat 
        [amount] => 1 Steak, one baked potatoe 
        [unit] => lunch 
        [time] => Array 
         (
          [hour] => 13 
          [min] => 31 
         ) 

       ) 

      [1] => Array 
       (
        [type] => weight 
        [amount] => 78.5 
        [unit] => KG 
        [time] => Array 
         (
          [hour] => 22 
          [min] => 22 
         ) 

       ) 

     ) 

) 

Первая запись в $this->data['Entry']['date'] является дата, которая должна использоваться всеми записями. И поскольку также отсутствует user_id, я создал функцию «beforeSave» в модели ввода. Это выглядит следующим образом:

function beforeSave() { 
    App::import('Component','Session'); 
    $this->Session = new SessionComponent(); 

    if (isset($this->data) && isset($this->data['Entry'])) { 
     $date = $this->data['Entry']['date']; 
     unset($this->data['Entry']['date']); 

     foreach ($this->data['Entry'] as $n => $entry) { 
      if (is_array($entry)) { 
      $this->data['Entry'][$n]['date'] = $date . ' ' . $entry['time']['hour'] . ':' . $entry['time']['min'] . ':00'; 
       $this->data['Entry'][$n]['user_id'] = $this->Session->read('Auth.User.id'); 
      } 
     } 
     debug($this->data); 

    } 
    return true; 
} 

Я удалить дату, добавить его вместе с записью времени пользователя, тем самым создавая запись DATETIME MySQL и добавить user_id вошедшего в систему пользователя. Прямо, правда. Полученный массив (как выход этой последней debug()) выглядит следующим образом:

Array 
(
    [Entry] => Array 
    (
     [0] => Array 
      (
       [id] => 1 
       [type] => Eat 
       [amount] => 1 Steak, 1 baked potatoe 
       [unit] => lunch 
       [time] => Array 
        (
         [hour] => 09 
         [min] => 31 
        ) 

       [date] => 2011-01-07 09:31:00 
       [user_id] => 2 
      ) 

     [1] => Array 
      (
       [type] => Weight 
       [amount] => 78.5 
       [unit] => KG 
       [time] => Array 
        (
         [hour] => 22 
         [min] => 22 
        ) 

       [date] => 2011-01-07 22:22:00 
       [user_id] => 2 
      ) 

    ) 

) 

Так выглядеть точно так, как я хочу, чтобы она выглядела, и это должно быть легко сохранены. Но когда я использую $this->Entry->saveAll($this->data['Entry']), чтобы сохранить все записи, это не только не работает, но когда я отлаживаю $this->data непосредственно после saveAll, он выглядит точно так же, как перед функцией saveAll - дата возвращается в массив, записи не записываются введите дату или user_id.

я могу видеть, что BeforeSave называется, я могу видеть, что он меняет $this->data, но где-то между концом BeforeSave и использования «SaveAll» все мои изменения заблудились и $this->data это вернулось в исходное состояние. Поэтому спасение не происходит.

ответ

6

У меня была схожая проблема, пытаясь реализовать некоторую санитацию с hasMany through. Как выясняется, проблема заключается в том, как работает функция saveAll().Данные $ this-> в контроллере не совпадают с данными $ this-> в обратном вызове Model :: beforeSave(), и оба они не синхронизированы. Когда вы вызываете Model :: saveAll(), передавая данные $ this-> с контроллера. Вы явно даете модель «старой версии» массива данных. И когда Вы смотрите в определение SaveAll в торте/LIBS модели// model.php он просто делает:

if (empty($data)) { 
    $data = $this->data 
} 

и больше ничего синхронизировать измененный массив $ данных в модели и передается по $ данных параметров образуют контроллер , Решение состоит в том, чтобы не передавать данные в файл saveAll(), а вместо этого сначала устанавливать данные в модели с помощью Model :: set(), а затем вызвать Model :: saveAll() (без параметра $ data).

+0

Это не сработает, по крайней мере, используя поведение ...: _ ( – elboletaire

0

насколько я знаю SaveAll() UpdateAll() и DeleteAll() Dont запускать какие-либо функции обратного вызова по умолчанию

Вам необходимо включить их вручную (последний параметр метода)

+0

Нет, обратный вызов был вызван просто отлично, поскольку отладка в функции beforeSave показывала новую структуру данных без заминки. – Sorcy

0

Вы не вы сработали на валидации?

Попробуйте

$this->Entry->saveAll($data,array('validate'=>false)); 

Если это работает, то проблема заключается в проверке

Однако не забывайте, что вам нужно использовать создать() перед сохранением для отдельных моделей, если не указан первичный ключ. Возможно, смешение новых и существующих данных в файле saveAll() является проблемой.

+0

Нет. Для этой модели не было подтверждения. Кроме того, поскольку я переместил мою функцию beforeSave в контроллер, она работает просто отлично. Я ничего не изменил в функциональности, но когда он вызывается в контроллере, структура данных сохраняется, когда она вызывается в beforeSave, это не так. – Sorcy

1

Когда мы вызываем SaveAll, не передаем обновленные/представленные данные в модель beforeSave. Для того, чтобы выйти из этой проблемы,

создать tmp_data массив в модели

т.е.

var $tmp_data = array(); 

перед тем SaveAll вызова, установите эту переменную, т.е.

$this->model->tmp_data = $this->data; 
$this->model->saveAll(); 

Затем изменить код модель-> beforeSaveBefore Вместо $this->data use $this->tmp_data

Смежные вопросы