Много към много, с друга колона

Чудя се дали някой се е сблъсквал с този проблем.
Да приемем, че имам две таблици: продукти и колички (свързани много към много).

Сега таблицата за обединяване има допълнителна колона - сума (колко продукта от определен тип има в количката).


Проблемът ми е, че не мога да получа достъп до колона "сума" чрез следната връзка:

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)


Внедряването на MANY_MANY на Yii има ограничения, които може да бъдат разгледани в по-късна версия на 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 и ще можете да актуализирате вашата „сума“.

Сега е подходящ момент да кажа, че не ми харесва вашият подход към проблема - наличието на колона "сума", която съдържа броя на продуктите в количката, защото трябва да запазите две истини (действителното количество продукти, които са картографирани към кошницата в db и полето "сума" на кеша на брояча в съответната таблица"). Ако имате много много тежко приложение, което се нуждае от тази денормализация на db, бих направил "контра връзка", за да получа броя на продуктите, вместо кеширане на тази стойност в колона, като тази (добавете следната връзка към вашия модел 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