andryam
(Andryam)
October 29, 2010, 4:29pm
1
интересует вопрос следующего характера, требуется вывести список фильмов по жанру переданный по гет параметру $_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’] жанру, как такое можно реализовать, точнее что в контролере описать?
MichaelMV
(Michmv)
October 29, 2010, 11:50pm
2
Определитесь по каким полям у вас какая таблица связана и поменяйте либо у 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/>";
}
andryam
(Andryam)
October 30, 2010, 12:12am
3
спасибо, сейчас попробую
кстати по приведённой вами ссылке там имеется описание отношения "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
andryam
(Andryam)
October 30, 2010, 1:45am
4
здорово, теперь всё работает, оказывается нужно было и в правду поменять местами id и type_id у Genres
andryam
(Andryam)
October 30, 2010, 3:31am
5
кстати, обнаружил что постраничник в этом случаи не работает, точнее работает но он только для жанров, а мне нужно для фильмов, есть какой выход?
ведь если будет на сайте 1000 фильмов, неужели все выводить на странице…
MichaelMV
(Michmv)
October 30, 2010, 11:18am
6
В первом случае нужно передать 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);
andryam
(Andryam)
October 30, 2010, 1:12pm
7
Спасибо, сделал также последний пример, с первым просто не разобрался с подставленением 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, разницы вроде не обнаружил
MichaelMV
(Michmv)
October 30, 2010, 3:15pm
8
Последний вариант будет побыстрее, потому как объединяет всего две таблицы, tbl_genres_types и tbl_films, а предыдущие целых три.
По поводу скорости, вы ее так особо не почуствуюте, нужно мерить под высокой нагрузкой.
andryam
(Andryam)
October 30, 2010, 3:20pm
9
хорошо спасибо, буду иметь введу, последний вариант оставлю на заметку на случай