есть таблица category_product, у category есть parent_id. легаси код собирает product_id из всех подкатегорий, чтобы в родительской категории показывать в том числе продукты из дочерних. отсюда этот массив.
я добавил в релейшен таблицу поле order, разбил получение товаров на две части (сначала основная, потом дочерние категории) с сортировкой по order.
предложенный тобой второй вариант заработал. подумаю еще, можно ли вообще все там переписать на нормальный релейшеншип, спасибо за советы!