Многие ко многим, с другой колонкой

Интересно, сталкивался ли кто с этой проблемой.
Предположим, у меня есть две таблицы: продукты и тележки (связанные со многими).

Теперь в объединяющей таблице появился дополнительный столбец - количество (сколько товаров определенного типа находится в корзине).


Моя проблема в том, что я не могу получить доступ к столбцу «количество» через следующее отношение:

public function relations()
{       
    return array(
           'products'=>array(self::MANY_MANY, 'Product', 'cart_products(cart_id, product_id)'),

    );
}

Я также пробовал:

'products'=>array(self::HAS_MANY, 'Product','product_id','through'=>'cart_products'),

без везения.


person mailo    schedule 26.07.2011    source источник


Ответы (1)


Реализация Yii MANY_MANY имеет ограничения, которые могут быть устранены в более поздней версии Yii.

Решением является использование еще одного модельного класса для таблицы MANY_MANY. Например, создайте AR-класс CartProduct, и тогда отношение для вашей корзины станет:

public function relations()
{       
    return array(
           'cartProducts'=>array(self::HAS_MANY, 'CartProduct', 'cart_id'),
           'products'=>array(self::HAS_MANY, 'Product', 'product_id', 'through' => 'CartProduct'),
    );
}

Таким образом, у вас будет ссылка на модель CartProducts в магическом публичном свойстве cartProducts экземпляра Cart и вы сможете обновить свою «сумму».

Теперь самое время сказать, что мне не нравится ваш подход к проблеме - наличие столбца «количество», в котором содержится количество продуктов в корзине, потому что вам нужно сохранить две истины (фактическое количество продуктов, которые отображаются на карте). в корзину в базе данных и поле "количество" кэша счетчика в соответствующей таблице "). Если у вас нет очень-очень тяжелого приложения, которое нуждается в денормализации базы данных, я бы сделал" встречное отношение ", чтобы получить количество продуктов, вместо кэширование этого значения в столбце, как это (добавьте следующее отношение к вашей модели корзины):

public function relations()
{       
    return array(
           'products'=>array(self::MANY_MANY, 'Product', 'cart_products(cart_id, product_id)'),
           'productsAmount'=>array(self::STAT, 'Product', 'cart_products(cart_id, product_id)'),

    );
}

Таким образом, вы можете вызвать свойство cart-> protuctsAmount, и оно вернет фактическую сумму с помощью простого и быстрого запроса подсчета (который, я думаю, будет кэшироваться) вместо того, чтобы полагаться на кешированное значение, которое должно быть восстановлено вашим кодом или db срабатывает каждый раз, когда вы меняете товары в корзине.

person ddinchev    schedule 26.07.2011
comment
Большое спасибо, это именно тот ответ, на который я надеялся. Магазин, над которым я работаю, не нуждается в каких-либо необычных функциях, таких как размер или цвет продукта (мне просто нужно, чтобы функция говорила: я хочу 5 из этих продуктов и 3 из них), поэтому я думаю, что в моем случае столбец количества выполняет свою работу, хотя я понимаю ваш подход и обязательно воспользуюсь им, если бы проект стал больше. - person mailo; 26.07.2011
comment
Спасибо, что не улучшили ситуацию OP, но также ответили на его вопрос - поскольку я столкнулся с подобной ситуацией, и ответ, который вы предоставили, очень полезен. - person Navarr; 20.07.2012