如何为关系查询配置Yii模型?

时间:2011-09-20 01:02:29

标签: php mysql relational-database yii

有点新的yii并且在我的gii生成的模型中尝试进行连接查询时遇到了麻烦。

要点:
我想要返回符合特定搜索条件的视频(表'视频')。要做到这一点,我有我的'视频'表,我有另一个表'搜索地图'。所有搜索地图都将video_id与search_id相关联,以便我可以跟踪符合单个搜索方案标准的多个视频。

我尝试了什么:
我试过跟yii docs for relational queries,但我想我还遗失了一些东西......下面是我的代码。我做错了什么?

注意:我希望使用CActiveDataProvider返回模型

表格

CREATE TABLE IF NOT EXISTS `videos` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `directory` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `created` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  `title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `description` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `category` int(2) NOT NULL,
  `tags` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `filename` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `filetype` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `duration` int(11) NOT NULL,
  `status` int(1) NOT NULL,
  `error` text COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=17 ;


CREATE TABLE IF NOT EXISTS `searchmaps` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `search_id` int(11) NOT NULL,
  `video_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=69 ;

类:

这是Controller类:

//From VideosController.php

 ...

public function actionIndex($searchmap_id)
{
    $dataProvider = new CActiveDataProvider('SearchVideos', array(
            'criteria' => array(
        'with' => array('search.video_id','search.search_id'),
        'together' => true,
            'condition'=>'videos.id = search.video_id AND search.search_id='.$searchmap_id,
                )));
        $this->render('index',array(
        'dataProvider'=>$dataProvider,
        ));
}

以下是主要的模型类:

// From Videos.php

...

/**
* @return array relational rules.
*/

public function relations()
{
   // NOTE: you may need to adjust the relation name and the related
   // class name for the relations automatically generated below.
   return array(
   'search'=>array(self::BELONGS_TO, 'Searchmaps', 'video_id'),
           );
}

以下是相关表格的模型类

// From Searchmaps.php

   ...

/**
* @return array relational rules.
*/

public function relations()
{
  // Each row has a search_id and a video_id relating to a specific video
  // Multiple rows may have different videos but share the same search_id
   return array(
    'video'=>array(self::HAS_ONE, 'Videos', 'video_id'),
    );
}

1 个答案:

答案 0 :(得分:3)

首先,我建议使用InnoDB表,以便设置正确的外键 - 如果你这样做,那么gii将为你生成基本关系。如果您可以转换表格,那么您可以添加fk:

ALTER TABLE `searchmaps`
ADD CONSTRAINT `searchmaps_ibfk_1` FOREIGN KEY (`video_id`) REFERENCES `videos` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE;

您的关系看起来不太正确,似乎应该是:

视频模型中的

return array(
    'searchmaps' => array(self::HAS_MANY, 'Searchmaps', 'video_id'),
);
在Searchmaps模型中:

return array(
    'video' => array(self::BELONGS_TO, 'Videos', 'video_id'),
);

然后你的dataProvider看起来像:

$dataProvider=new CActiveDataProvider('Videos',array(
    'criteria'=>array(
        'with'=>'searchmaps',
        'together' => true,
        'condition' => 'searchmaps.search_id='.$search_id,
    )
));

尝试它可以在视图中输出一个简单的网格,例如:

$this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'videos-grid',
    'dataProvider'=>$dataProvider
));

同样,我强烈建议在表格中使用外键并查看关系gii输出,一旦你了解它正在做什么,它将更容易定制。此外,使用外键将确保维持关系。如果需要帮助创建外键,可以使用MysqlWorkbench等工具。