запрос с MANY_MANY и with

Может торможу конечно, но…

в модели Item

public function relations()

{

        return array(

            'fotos'=>array(self::HAS_MANY, 'Fotos', 'itemID'),

  'categories'=>array(self::MANY_MANY, 'Category', 'ItemCategory(itemID, categoryID)',

  ),

        );

}

хочу вывести записи по конкретной категории $catid:

$withOption = array();

$withOption['categories']['alias']='categories';

$withOption['categories']['condition']="??.id='{$catid}'";

$criteria=new CDbCriteria;

$criteria->select = array('id','name');

$itemList=Item::model()->with($withOption)->findAll($criteria);

получаю полный список item безотносительно к $catid

запрос SQL выглядит так:

SELECT Item.id AS t0_c0, categories.id AS t1_c0, categories.name AS t1_c1, categories.description AS t1_c2, categories.is_visible AS t1_c3 FROM Item LEFT OUTER JOIN ItemCategory categories_categories ON (Item.id=categories_categories.itemID) LEFT OUTER JOIN Category categories ON (categories.id=categories_categories.categoryID) AND (categories.id='3')  WHERE (Item.id IN (2, 30, 31, 32, 33, 34, 35))

и результат такой:

Posted Image

хотя я надеялся увидеть такой:

Posted Image

что я делаю неправильно?

Видимо у тебя есть категории с id 2,30,34 в которых ничего нету.

И вообще - если ты выводишь к конкретной категории записи, то не логичнее ли вызывать Category::model()->with('items')->findAll();

Ты как-то наизнанку вытаскиваешь все

Quote

Видимо у тебя есть категории с id 2,30,34 в которых ничего нету.

И вообще - если ты выводишь к конкретной категории записи, то не логичнее ли вызывать Category::model()->with('items')->findAll();

Ты как-то наизнанку вытаскиваешь все

2, 30, 34 это id из items

запрос выводит ВСЕ items и связанные с ними категории где $catid = 3, а я надеюсь получить только items где $catid = 3

мне надо вывести именно items и названия категорий, где они присутствуют

на самом деле - тут всё упрощено до предела, в реальной базе 8 связанных на items таблиц, но вот relations many_many какой-то затык

Так, давай сначала правильно задачу поставим -

вывести итемы с id (2, 30, 31, 32, 33, 34, 35) при условии что они в категории с id 3?

если я правильно понял, то проще вообще having заюзать :) вообще вся причина в left join и кажется оно как-то меняться может… надо покапаться в доках

Quote

Так, давай сначала правильно задачу поставим -

вывести итемы с id (2, 30, 31, 32, 33, 34, 35) при условии что они в категории с id 3?

если я правильно понял, то проще вообще having заюзать :) вообще вся причина в left join и кажется оно как-то меняться может… надо покапаться в доках

не итемы с id (…) а все итемы где catid = 3. having можно было бы юзать, если бы было поле catid у итемсов, а они свзяны с категориями через промежуточную таблицу с MANY_MANY

Тут нужен всего один join с промежуточной таблицей т.к. id категории мы уже имеем.

Quote

Тут нужен всего один join с промежуточной таблицей т.к. id категории мы уже имеем.

да кто бы спорил - вручную я напишу любой запрос, зачем мне тогда все релейшены и кондишены…

вопрос-то в том, что я прописал relations и прописал condition, по-моему правильно это сделал, сделал запрос - получаю на выходе не то что ожидал…

склонен всё-таки думать, что я где-то лопухнулся и кто-то увидит логику…

Меня смущает LEFT OUTER JOIN… Я могу ошибаться, но попробуйте joinType => INNER JOIN (по умолчанию это LEFT OUTER JOIN: http://www.yiiframew…i/CActiveRecord).

Quote

Меня смущает LEFT OUTER JOIN... Я могу ошибаться, но попробуйте joinType => INNER JOIN (по умолчанию это LEFT OUTER JOIN: http://www.yiiframew...i/CActiveRecord).

Ой спасибо! Правда, помогло только на одном запросе, когда включил остальные релейшены - всё опять наперекосяк… Поставил во все релейшены INNER JOIN и добавил ещё togeher() в запрос и тут всё стало нормально. Хотя шаманство какое-то…  :)

Quote

Quote

Меня смущает LEFT OUTER JOIN... Я могу ошибаться, но попробуйте joinType => INNER JOIN (по умолчанию это LEFT OUTER JOIN: http://www.yiiframew...i/CActiveRecord).

Ой спасибо! Правда, помогло только на одном запросе, когда включил остальные релейшены - всё опять наперекосяк… Поставил во все релейшены INNER JOIN и добавил ещё togeher() в запрос и тут всё стало нормально. Хотя шаманство какое-то…  :)

Ну если почитать про различия LEFT OUTER и INNER JOIN, то становится ясно, что при LEFT OUTER всегда будут возвращаться все записи первой таблицы. Судя по результатам в первом посте, так оно и происходило.