добавление массива флажков в проверку формы kohana

Возникли проблемы с добавлением значений флажка в БД через orm

Работает для обычных полей, но не в том случае, если в вопросах с флажками установлено более одного флажка, допускающих более одного варианта.

Вот бит формы

<?php echo Form::label('first_name', 'First Name')?><br />
<?php echo Form::input('first_name', $profile->first_name, array('class'=>'inputbox')); ?><br />


<?php echo Form::label('last_name', 'Last Name')?><br />
<?php echo Form::input('last_name', $profile->last_name, array('class'=>'inputbox')); ?><br />

Favorite Genres: 
<label><input type="checkbox" value="Horror"  name="genres[]"  />
<strong>Horror</strong></label><br />
<label><input type="checkbox" value="Thriller"  name="genres[]"  />
<strong>Thriller</strong></label><br />

Вот бит контроллера

if ($_POST) {
    if ($profile->values($_POST)->check()) {
        $profile->user_id = $user;
        $profile->save();
    }
}

А вот и моделька

protected $_rules = array(

'first_name' => array(
    'not_empty' => NULL,

),

'last_name' => array(
    'not_empty' => NULL,

),


);

Только не работает, когда выбрано более одного флажка, я получаю эту ошибку

Database_Exception [ 1241 ]: операнд должен содержать 1 столбец (столбцы)

Не уверен, что это лучший подход. Должен ли я сериализовать или взорвать? Где это сделать?

В будущем я хочу создать базовую форму поиска для поиска «подобных» значений с использованием этого столбца.


person user1019144    schedule 13.06.2012    source источник
comment
Где код, который фактически обрабатывает данные флажка? У вас в модели только имя и фамилия...   -  person Thorsten    schedule 14.06.2012
comment
Кода пока нет, поэтому мне нужна помощь   -  person user1019144    schedule 15.06.2012


Ответы (2)


Это DB исключение, а не Validation. Вы должны использовать отношения ORM для этой ситуации:

class Model_Profile extends ORM {

   protected $_has_many = array(
       // profile has and belongs to many genres
       'genres'  => array(
            'through' => 'profiles_genres', // pivot table name
       ),
   );
}

А затем измените жанры для текущего профиля, например:

try 
{
   $profile->check();
   $profile->save();
   // now replace old genres with a new list
   // clear genres
   $profile->remove('genres');
   foreach($this->request->post('genres') as $genre) 
   {
       $genre = ORM::factory('genre')->where('name', '=', $genre);
       if ($genre->loaded()) 
       {
           $profile->add('genres', $genre);
       }
   }
}
catch (Validate_Exception) 
{
    // wrong input
}

Обратите внимание, что не genres разделены таблицей, а не profiles столбцом. Также вам понадобится сводная таблица profiles_genres со столбцами profile_id и genre_id.

person biakaveron    schedule 14.06.2012
comment
Спасибо. На самом деле я не собираюсь создавать новые таблицы, учитывая, что у меня будет около дюжины таких многотекстовых полей для профилей пользователей. - person user1019144; 14.06.2012
comment
Вы можете хранить их в виде строк JSON. Нет необходимости в специальных таблицах, но вы не можете использовать стандартные функции БД, такие как фильтры. - person biakaveron; 16.06.2012

Вы должны создать таблицу жанров и модель, а также создать сводную таблицу для жанров и профилей:

CREATE TABLE IF NOT EXISTS `genres` (
  `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `uniq_name` (`name`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `genres_profiles` (
  `profile_id` int(10) UNSIGNED NOT NULL,
  `genre_id` int(10) UNSIGNED NOT NULL,
  PRIMARY KEY  (`profile_id`,`genre_id`),
  KEY `fk_genre_id` (`genre_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Обратите внимание, что вам не нужно создавать модель ORM для сводной таблицы.
Дополнительную информацию можно найти в официальные документы

person matino    schedule 14.06.2012
comment
я бы предпочел не создавать больше таблиц, как я уже говорил, это всего лишь один из многих вопросов с флажками. Не могли бы вы предложить альтернативный способ. По сути, я бы просто взорвал массив в строку, прежде чем он будет вставлен. Где лучше всего это сделать? - person user1019144; 15.06.2012