Как привязать первичный ключ к пользовательскому условию ON в отношениях Yii?

Проблема:

Как связать первичный ключ с запросом пользовательского отношения?

Контекст, зачем:

Один Источник может относиться к нескольким различным Модификациям (MANY_MANY), каждая модификация относится к какому-то Продукту (BELONGS_TO). Если у нескольких Продуктов один Источник, это означает, что Продукты одинаковые - это критерий. (Я не могу просто объединить одинаковые продукты, потому что может оказаться, что они не одинаковы, но если я их объединим - я не смогу разделить их обратно).

Итак, когда мне нужно найти все заказы, связанные с каким-либо продуктом, я действительно хочу найти все заказы с одними и теми же продуктами, а не только с текущим продуктом.

Отношение выглядит следующим образом:

'orderedProducts'=>array(self::HAS_MANY,'OrderProduct','','on'=>('modification_id IN (
select DISTINCT ms2.modification_id FROM products p1
LEFT JOIN products_modifications pm ON pm.product_id = p1.product_id
LEFT JOIN modifications_sources ms ON ms.modification_id = pm.modification_id
LEFT JOIN modifications_sources ms2 ON ms2.source_id = ms.source_id
where p1.product_id='.$this->primaryKey.'
)')),

'orders'=>array(self::HAS_MANY,'Order',array('order_id'=>'order_id'),'through'=>'orderedProducts'),

$this->primaryKey не работает. Здесь просто показано, где мне нужно связать первичный ключ.

Любые предложения, как связать первичный ключ там?


person Max Zhuravlev    schedule 08.05.2013    source источник


Ответы (1)


Это довольно сложный запрос, и было бы гораздо удобнее реализовать эту функциональность, определив геттер getOrderedProducts() для модели. Внутри этого геттера вы можете получить первичный ключ вашей модели просто с помощью $this->primaryKey. Затем вы сможете получить заказанные продукты из вашей модели по атрибуту $model->orderedProject, как если бы вы сделали это с помощью отношений. И, в качестве бонуса, вы можете реализовать кэширование для такого тяжелого запроса.

Что касается отношения, мое исследование, проведенное путем регистрации запросов к SQL, созданных при доступе к полю отношения HAS_MANY модели, показывает, что YII будет связывать первичный ключ модели с одним из именованных параметров: ypl0, :ypl1... и т. д. Итак, если вас устраивает какой-то грязный хак, вы можете получить доступ к первичному ключу вашей модели с помощью связанного параметра:

'orderedProducts'=>array(self::HAS_MANY,'OrderProduct','','on'=>('modification_id IN (
select DISTINCT ms2.modification_id FROM products p1
LEFT JOIN products_modifications pm ON pm.product_id = p1.product_id
LEFT JOIN modifications_sources ms ON ms.modification_id = pm.modification_id
LEFT JOIN modifications_sources ms2 ON ms2.source_id = ms.source_id
where p1.product_id=:ypl0'

но вы должны убедиться, что YII привязывает первичный ключ к первому (: ypl0) из его параметров (это будет верно, если вы не привязываете какие-либо параметры самостоятельно). В любом случае, я рекомендую полагаться на первый подход, определив геттер как более стабильный и настраиваемый.

person Serj Zaharchenko    schedule 23.07.2013