вывести список по одному из жанров (MANY_MANY)

интересует вопрос следующего характера, требуется вывести список фильмов по жанру переданный по гет параметру $_GET[‘genre_id’]

Имеется такие модели

Films


public function relations()

{					   

 return array(                                                              																		   

	'genres' => array(self::MANY_MANY, 'Genres', 'tbl_genres_types(id, type_id)'),

 );

} 

Genres


public function relations()

{

 return array(

	'films' => array(self::MANY_MANY, 'Films', 'tbl_genres_types(id, type_id)'),		

 );

}	

Имеется таблица с фильмами tbl_films где каждый фильм может иметь как один так и несколько жанров, жанры хранятся в другой таблице tbl_genres есть также промежуточная таблица(tbl_genres_types) которая хранит связи.

Нужно вывести фильмы не все сразу а только по заданному $_GET[‘genre_id’] жанру, как такое можно реализовать, точнее что в контролере описать?

Определитесь по каким полям у вас какая таблица связана и поменяйте либо у Film, либо Genres id и type_id местами.


array(self::MANY_MANY, '...', 'tbl_genres_types(type_id, id)'),

Классический вариант (описан в доках)

Контроллер


$model = Genres::model()->with('films')->findByPk($_GET['genre_id']);

Если нужно как то отфильтровать вывод фильмов то почитайте это и это

В отображении


foreach($model->films as $i) {

    echo "{$i->id} - {$i->name}<br/>";

}

Еще можно более извращенно

Контроллер


$criteria = new CDbCriteria;


$model = Films::model()->with(array(

    'genres'=>array(

            'joinType'=>'RIGHT OUTER JOIN',

            'condition'=>'genres.id = :id',

            'params'=>array(':id'=>$_GET['genre_id'])

        ),

    ))->findAll($criteria);

CDbCriteria это если вы хотите как то отфильтровать фильмы, а так это можно опустить

В отображении


foreach($model as $i) {

    echo "{$i->id} - {$i->name}<br/>";

}

спасибо, сейчас попробую

кстати по приведённой вами ссылке там имеется описание отношения "categories" промежуточной таблицы post_category

у меня та же ситуация, только там нет описания как вывести записи определённого раздела

кстати в моём случаи

id: id фильма

type_id: id жанра

к примеру

id | type_id

5 | 6

7 | 8

5 | 12

3 | 6

первая колонка id фильмов, вторая колонка id жанров

отсюда если я через гет параметр передаю раздел id 6, то я должен получить фильмы с id 5 и 3

А если передам раздел с id 8, то получить должен только фильм с id 7

здорово, теперь всё работает, оказывается нужно было и в правду поменять местами id и type_id у Genres

кстати, обнаружил что постраничник в этом случаи не работает, точнее работает но он только для жанров, а мне нужно для фильмов, есть какой выход?

ведь если будет на сайте 1000 фильмов, неужели все выводить на странице…

В первом случае нужно передать limit и offset, как это делать я дал две ссылки выше.

Но проще взять второй вариант и сделать как написано в документации


$criteria = new CDbCriteria();


$count = Films::model()->with(array(

    'genres'=>array(

            'joinType'=>'RIGHT OUTER JOIN',

            'condition'=>'genres.id = :id',

            'params'=>array(':id'=>$_GET['genre_id'])

        ),

    ))->count($criteria);

$pages=new CPagination($count);


$pages->pageSize=10;

$pages->applyLimit($criteria);

$model = Films::model()->with(array(

    'genres'=>array(

            'joinType'=>'RIGHT OUTER JOIN',

            'condition'=>'genres.id = :id',

            'params'=>array(':id'=>$_GET['genre_id'])

        ),

    ))->findAll($criteria);

Спасибо, сделал также последний пример, с первым просто не разобрался с подставленением offset и т.п.

Приведу ещё один пример, который описывается автором


	public function actionList()

	{

	

		if(isset($_GET['genre_id'])  ){

			$type = FilmsGenres::model()->findByPk($_GET['genre_id']);

		}                    

			  

		if ($type !== null) { 

		

		   $criteria = new CDbCriteria; 

					       

			$pages=new CPagination(count($type->getRelated('films')));

			$pages->pageSize=50;


			$params = array(

				'offset'=>$pages->offset,

				'limit'=>'50',

			);

						  

			$model = $type->getRelated('films',false, $params); 

			

		} else {

			echo 'not';

		} 

	}

	

этот кстати тоже заработал после того как вы сказали поменять местами type_id и id

Но вот стало теперь интересно, какой из этих вариантов будет лучше, в частности по производительности, можно как то узнать?

сам я нажатием F5 и стандартным отчётом Yii, разницы вроде не обнаружил

Последний вариант будет побыстрее, потому как объединяет всего две таблицы, tbl_genres_types и tbl_films, а предыдущие целых три.

По поводу скорости, вы ее так особо не почуствуюте, нужно мерить под высокой нагрузкой.

хорошо спасибо, буду иметь введу, последний вариант оставлю на заметку на случай