2009-02-17 5 views
-1

Я пытаюсь обновить таблицы с помощью has и принадлежит ко многим (HABTM) отношениям.Сохранение записей HABTM, когда не все столбцы столбцов являются внешними ключами

Когда мой присоединиться к таблице выглядит следующим образом:

CREATE TABLE IF NOT EXISTS `items_labels` (
    `item_id` int(11) NOT NULL, 
    `label_id` int(11) NOT NULL 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

Я использую CakePHP, так что я мог бы обновить таблицы с $ this-> item-> сохранить ($ данные), где $ данные были:

Array 
(
    [Item] => Array 
     (
      [id] => 1 
     ) 
    [Label] => Array 
     (
      [Label] => Array 
       (
        [0] => 4 
        [1] => 5 
        [2] => 7 
        [3] => 8 
       ) 
     ) 
) 

Я добавил колонку к моему присоединиться к столу, так что теперь выглядит следующим образом:

CREATE TABLE IF NOT EXISTS `items_labels` (
    `item_id` int(11) NOT NULL, 
    `label_id` int(11) NOT NULL, 
    `user_id` int(11) NOT NULL 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

Когда я спасаю $ данных, я также хочу, чтобы сохранить идентификатор пользователя. Идентификатор пользователя будет одинаковым для всех записей в одной операции сохранения.

Может кто-нибудь помочь мне понять, как должен выглядеть массив данных $, чтобы включить идентификатор пользователя? Благодарю.

+0

Замените тег 'mysql' на 'cakephp'. – skypher

ответ

2

Это должно работать:

Array 
(
    [Item] => Array 
     (
      [id] => 1 
     ) 

    [Label] => Array 
     (
      [Label] => Array 
       (
        [0] => Array 
         (
          [label_id] => 4 
          [user_id] => 1 
         ) 

        [1] => Array 
         (
          [label_id] => 5 
          [user_id] => 1 
         ) 

        [2] => Array 
         (
          [label_id] => 7 
          [user_id] => 1 
         ) 

        [3] => Array 
         (
          [label_id] => 8 
          [user_id] => 1 
         ) 

       ) 

     ) 

) 

Он будет генерировать несколько топок, но будет работать с одним экономии вызов.

+0

Привет, Мэтт, я читал ваш блог раньше. Приятно получить от вас ответ на SO. Благодарю. –

1

Модель CakePHP :: save() не сделает это для вас AFAIK. Я думаю, вы должны использовать model :: saveAll() и называть его моделью «с». CakePHP автоматически узнает вашу таблицу соединений и может ее смоделировать без необходимости создания физического файла модели и класса. Все, что вам нужно сделать, это форматировать массив данных в формате saveAll.

Я не пробовал, но что-то вроде следующего должно работать.

<?php 
class Item extends AppModel { 
    var $name = 'Item'; 
    var $_habtmData = null; 
    function beforeSave() { 
    $this->unbindModel(array('hasAndBelongsToMany' => array('Label'))); 
    $this->_habtmData = $this->data['Label']; 
    } 
    function afterSave() { 
    if (is_array($this->_habtmData) && !empty($this->_habtmData)) { 
     foreach ($this->_habtmData['Label'] as $k => $labelId) { 
     $this->_habtmData['Label'][$k] = array(
      'item_id' => $this->id, 
      'label_id' => $labelId, 
      'user_id' => $userId, // Get this from somewhere 
     ); 
     } 
     $this->bindModel(array('hasMany' => array('ItemsLabel'))); 
     $this->ItemsLabel->saveAll($this->_habtmData); 
    } 
    } 
} 
?> 

Все это делается в модели (как и должно быть), поэтому ваш контроллер и виды остаются чистыми. Мы делаем все это в afterSave, поэтому он только пытается, если данные элемента проверяются.

По существу, мы временно отвязываем элемент hasAndBelongsToMany Label-ассоциации в beforeSave, поэтому данные HABTM не сохраняются, и мы сохраняем данные HABTM в свойстве модели, поэтому мы можем использовать его в afterSave (хотя это, вероятно, все равно доступны в любом случае).

Затем мы привязываем модель «с» к элементу с ассоциацией hasMany и форматируем данные в соответствии с требованиями базовой модели CakePHP :: saveAll(), прежде чем, наконец, назовем ее моделью «с», передав в новые данные.

Он должен работать в теории - удачи и дайте мне знать, как вы получите на ;-)

+0

Эй, спасибо за подробный ответ. Подход Мэтта Карри работал для меня и был намного проще. У меня есть ваш ответ, который может быть полезен, если я столкнулся с ситуацией с более сложными данными HABTM. –