Php Yii-使用关系的CActiveDataProvider

Php Yii-使用关系的CActiveDataProvider,php,activerecord,yii,Php,Activerecord,Yii,我试图将关系作为标准的一部分来创建cactivedaptaprovider。我有以下资料: 用户模型: return array( 'favourites'=>array(self::HAS_MANY, 'UserFavourite', 'user_id', 'order'=>'added_at DESC'), ); 用户最喜爱的型号: return array( 'user'=>array(self::BELONGS_TO, 'User',

我试图将关系作为标准的一部分来创建
cactivedaptaprovider
。我有以下资料:

用户模型:

return array(
        'favourites'=>array(self::HAS_MANY, 'UserFavourite', 'user_id', 'order'=>'added_at DESC'),
);

用户最喜爱的型号:

return array(
        'user'=>array(self::BELONGS_TO, 'User', 'user_id'),
        'listing'=>array(self::BELONGS_TO, 'Listing', 'listing_id'),
);

控制器(查看收藏夹操作):


如何在我的用户模型中创建一个
cactivedaptrovider
,获取当前用户的所有
收藏夹
,以及每个收藏夹的相关
列表
模型数据?所以我想做一些类似于
$favorites=$user->getfavorites()的事情

CActiveDataProvider
应该返回一个
列表
对象数组。它应该支持分页和排序-默认排序将添加到DESC


我曾尝试使用
CDbCriteria
选项,但似乎不起作用

您还没有提供数据库模式,但我想这段代码可以工作

$criteria=new CDbCriteria();
$criteria->with=array('favourites'=>array('with'=>'listing'));
$dataProvider= new CActiveDataProvider('User', array(
        'criteria'=>$criteria,
        'sort'=>array(
            'defaultOrder'=>'t.added_at DESC',
        )));
请确保您的关系正确且符合架构

  • 事实上,如果你不关心查询的数量,你可以随时调用

    $user->favorites

它将返回正确关系的正确数据,您也可以这样做

为了,将列表模型传递给视图,如下所示

foreach($user->favourites as $fav){

  $this->renderPartial("PATH TO YOUR VIEW",array('data'=>$fav->listing));

}
请注意,用户可能有许多收藏夹,因此您需要使用foreach,除非您没有使用CListview
另一种方法是使用Clistview,在这种情况下,您可能需要更改查询。让我知道这对您是如何工作的。

在您的
列表
方法中,您需要与
Users
通过中间表
UsersFavourite
。关系类型 有很多:

return array(
         'favourites'=>array(self::HAS_MANY, 'UserFavourite', 'listing_id'),
         'users'=>array(self::HAS_MANY, 'User', array('user_id'=>'id'), 'through'=>'favourites')
);
在返回
CActiveDataProvider
User
方法中:主模型 是
列表
,加入到
用户收藏夹
用户
。您必须同时设置
to
true
构建一个sql查询。最后,必须将users.id设置为
User
model的当前id,仅显示与当前用户相关的行

$criteria = new CDbCriteria;
$criteria->with = array( 'favourites','users =>'array('condition'=>"users.id=:user_id"));
$criteria->together = true;
$criteria->params = array(':user_id'=>$this->id);

return new CActiveDataProvider('Listing', array(
        'criteria'=>$criteria,
        'sort'=>array('defaultOrder'=>'favourites.added_at DESC')
));

我测试了这个答案,并用一个小数据集正确地工作

以下是我如何获得所需输出的:

$criteria = new CDbCriteria;
$criteria->condition = 'uf.user_id = :user_id';
$criteria->params = array(':user_id'=>$this->id);
$criteria->join = 'LEFT OUTER JOIN user_favourite uf ON uf.listing_id = t.id';
$criteria->order = 'uf.added_at DESC';

return new CActiveDataProvider('Listing', array(
    'criteria'=>$criteria,
));

最后,我只是在JOIN中硬编码,而不是尝试使用关系,因为它似乎不适合这样工作。

恐怕这不起作用。因为CActiveDataProvider正在加载
用户
类,但是我的视图文件需要一个
列表
类。它必须返回
列表
类对象的数组。关系是正确的,我可以按照您的建议通过执行
$user->favorites
来获得正确的数据,但问题是它不允许我使用该关系作为我的CActiveDataProvider的源。另外,我知道我可以创建一个单独的函数,该函数将返回所需的数据,而无需使用关系。但我不想重复任何代码。这是我们必须接受的限制吗?如果您的视图文件需要列表模型,为什么不将列表模型传递给视图,查看编辑的答案以了解详细信息。事实上,我使用的是CListView。因此,我无法传递列表模型,我只能指定一个
数据提供程序
值。在这种情况下,您需要修改查询并创建数据提供程序以供列表使用,回答@codeFX似乎是正确的,为什么不尝试一下呢。
$criteria = new CDbCriteria;
$criteria->condition = 'uf.user_id = :user_id';
$criteria->params = array(':user_id'=>$this->id);
$criteria->join = 'LEFT OUTER JOIN user_favourite uf ON uf.listing_id = t.id';
$criteria->order = 'uf.added_at DESC';

return new CActiveDataProvider('Listing', array(
    'criteria'=>$criteria,
));