CI: запрашивая две таблицы в модели, взорваться

0

Я думаю об этом в течение нескольких дней и не прихожу к схваткам (так как я релятивирую новичок в MVC и CI). Я даже не уверен, что это проблема с MVC, MySQL или массивами.

Ситуация: 2 таблицы MySQL

  • Данные таблицы: id, title, list
  • Значения таблиц: id, name

Запрос таблицы данных приводит к массиву, подобному следующему (выдержка):

[4] => Array
        (
            [id] => 3
            [title] => Foo                
            [list] => 1,2,3,4,6,14
        )

[5] => Array
        (
            [id] => 4
            [title] => Bar                
            [list] => 2,6,9,12
        )

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

[3] => Array
            (
                [id] => 12
                [name] => 'value12'                
            )

Что я пытаюсь сделать для каждой строки:

  • взять значения списка и взорвать его в массив
  • проверить с помощью набора результатов из таблицы значений (с помощью метода in_array())
  • возвращает значения имен идентификаторов, если
  • включить его как-то в основной результирующий набор (например, как 2-мерный массив):

    [5] = > Массив (               [id] = > 4               [title] = > Бар               [list] = > Массив (                                  [0] = > значение6                                  [1] = > значение12                                  ...                               )            )

Мой наивный подход до сих пор заключался в

  • выполнить запрос для каждой из двух таблиц
  • сравнить 2 набора результатов через in_array

Моя основная проблема (при попытке строго отделить модель, контроллер и представление): Как я могу включить поле имени из таблицы значений в "основной цикл" набора результатов таблицы данных?

if($q->num_rows() > 0)
{
    $data[] = $q->result_array();
    foreach ($q->result() as $row)
    {
        $data[] = $row;
    }
    return $data;
}

Если я использую следующий (громоздкий) подход, я, естественно, каждый раз получаю новый элемент:

foreach ($q->result_array() as $row) 
{
    $data[]['id'] = $row['id'];
    $data[]['title'] = $row['title'];
    $data[]['list'] = $row['year'];
}

Так как это база данных MySQL, я не вижу возможности сделать разложение и сравнение в SQL (с LIKE или чем-то еще).

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

Спасибо триллион!

FAB

Теги:
multidimensional-array
codeigniter
explode
resultset

1 ответ

1
Лучший ответ

Между списками и значениями списка существует взаимосвязь "многие-ко-многим". Обычным способом моделирования этого в реляционной базе данных является создание таблицы соединения. Поэтому я бы структурировал вашу схему следующим образом.

lists : list_id, title
values : value_id, name
list_values : list_id, value_id

list_values - таблица соединения. Он связывает списки со значениями.

Чтобы создать список, у вас могут быть следующие функции в вашей модели.

function build_list($list_id)
{
    $list = $this->get_list($list_id);
    $list->values = $this->get_list_values($list_id);
    return $list;
}

function get_list($list_id)
{
    $sql = 'select * from lists where list_id=?';
    return $this->db->query($sql, array($list_id))->row();
}

function get_list_values($list_id)
{
    $sql = 'select v.value_id, v.name
        from list_values lv
        join values v on v.value_id=lv.value_id
        where lv.list_id=?';
    return $this->db->query($sql, array($list_id))->result();
}
  • 0
    Абсолютно. Каждый раз, когда вы думаете о сохранении списка идентификаторов, разделенных запятыми, в столбце таблицы, это сильный сигнал, что вы, вероятно, делаете что-то не так.
  • 0
    Вы, ребята, абсолютно правы. Конечно, отношения многие ко многим всегда с таблицей соединений! большое спасибо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню