在询问之前,我试着"做作业",但我尝试的方法似乎都不起作用,所以我需要帮助。(我不是Yii的专家)
我的问题是,我希望在我的索引页面上有一个搜索框,它可以帮助我按标签搜索电影。我发现了一篇有用的文章,所以基本上我就是这样开始的。
我有以下表格:
电影
标签
movie_has_tag(其中包含movie_id和tag_id)
//我想我需要的是movie_title和tag_name
BaseMovie:中的关系
public function relations(){
return array(
'tags' => array(self::MANY_MANY, 'Tag', 'movie_has_tag(movie_id, tag_id)'),
);
}
BaseTag:中的关系
public function relations(){
return array(
'movies' => array(self::MANY_MANY, 'Movie', 'movie_has_tag(tag_id, movie_id)'),
);
}
我是这样尝试的:
public function actionIndex(){
if( isset($_GET['q']) ){
$model = new Movie($scenario='search');
$model->unsetAttributes();
$tag = $_GET['q'];
// this is how I tried
$tags = Movie::model()->with('tags')->findAllByAttributes( array('movie_title' => $tag));
$this->render('index',array(
'dataProvider'=>$model->search(),
));
}
使用此代码,当我开始在搜索框中键入时,不会发生任何事情。
编辑:
@Stu
我已经阅读了链接,并提出了以下内容。我将此关系添加到BaseMovie:
'tagz' => array(self::HAS_MANY, 'Tag', array('movie_id'=>'tag_id', 'through'=>'MovieTags')).
然后我编辑了正在操作的东西索引:
if( isset($_GET['q']) ){
$model = new Movie($scenario='search');
$model->unsetAttributes();
$movies = Movie::model()->withTag($_GET['q'])->findAll();
$tags = $movies->movieTags;
}
当我开始输入即时搜索框时,它就变成了咒语,所有的电影都消失了(即使我删除了输入的内容,它们也不会回来。我必须刷新页面)。
编辑v2:视图非常简单(_V):
<div class="view">
<?php echo CHtml::encode($data->title); ?>
</div>
其他一切(比如索引页)都和我第一次提到的链接一样。
好的,我已经阅读了你在这里写的内容(问题和第一个答案),并将在你的"EDIT:@Stu"标记之前解决你的问题,因为在那之后你开始做一些我不理解的奇怪事情。
您有两个型号Movie
和Tag
。Movie
模型中的关系如您之前所写:
public function relations(){
return array(
'tags' => array(self::MANY_MANY, 'Tag', 'movie_has_tag(movie_id, tag_id)'),
);
}
Tag
模型中的关系与您之前所写的相同:
public function relations(){
return array(
'movies' => array(self::MANY_MANY, 'Movie', 'movie_has_tag(tag_id, movie_id)'),
);
}
现在您可以在Movie
模型中创建新方法:
public function searchByTag($q)
{
$criteria=new CDbCriteria;
$criteria->with = 'tags';
$criteria->together = true;
$criteria->compare('`tags`.`name`', $q, true, 'OR');
// You can add here another comparision to search in your movie title, for example
// $criteria->compare('`t`.`title`', $q, true, 'OR');
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
在你的控制器中,动作应该是这样的:
public function actionIndex() {
if( isset($_GET['q']) ) {
$tag = $_GET['q']; // Please add needed safety measures, for example with HTMLPurifier
$this->render('index', array(
'dataProvider'=>Movie::model()->searchByTag($tag),
));
} else
$this->render('index');
}
希望这是有用的。