简体   繁体   English

Yii - 使用关系的CActiveDataProvider

[英]Yii - CActiveDataProvider using relations

I am trying to use relations as part of the criteria to create a CActiveDataProvider . 我试图使用关系作为标准的一部分来创建CActiveDataProvider I have the following: 我有以下内容:

User model: 用户模型:

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

UserFavourite model: UserFavourite模型:

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

Controller (view favourites action): 控制器(查看收藏夹操作):

$user = $this->loadUser(Yii::app()->user->id);

How do I create a CActiveDataProvider in my User model that fetches all favourites by the current user - along with the related listing model data for each favourite? 如何在我的用户模型中创建CActiveDataProvider ,以获取当前用户的所有favourites - 以及每个收藏夹的相关listing模型数据? So I want to do something like $favourites = $user->getFavourites(); 所以我想做一些像$favourites = $user->getFavourites(); .

The CActiveDataProvider should return an array of Listing objects. CActiveDataProvider应该返回一个Listing对象数组。 It should support pagination and sorting - the default sort will be added_at DESC . 它应该支持分页和排序 - 默认排序将是added_at DESC

I have tried using the with option of CDbCriteria but that does not seem to work... 我尝试过使用CDbCriteriawith选项,但这似乎不起作用......

You have not provided your database schema, but i guess this code could work, 您还没有提供数据库架构,但我想这段代码可以工作,

$criteria=new CDbCriteria();
$criteria->with=array('favourites'=>array('with'=>'listing'));
$dataProvider= new CActiveDataProvider('User', array(
        'criteria'=>$criteria,
        'sort'=>array(
            'defaultOrder'=>'t.added_at DESC',
        )));

Please make sure your Relations are correct and according to schema. 请确保您的关系正确且符合架构。

  • Infact, If you dont care about number of queries, you can always call something like 事实上,如果你不关心查询的数量,你可以随时调用类似的东西

    $user->favourites; $用户>收藏夹;

It will return proper data for correct relations, Again you can do this 它将返回正确关系的正确数据,您可以再次执行此操作

In order to , pass listing model to view go like this 为了 ,通过列表模型查看就像这样

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

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

}

Note that there may be many Favourites for an user so you need to use foreach , unless you are not using CListview . 请注意,用户可能有许多收藏夹,因此您需要使用foreach,除非您不使用CListview Another way is to user Clistview in that case you may need to change your query.Let me know how that works for you. 另一种方法是用户Clistview,在这种情况下,您可能需要更改您的查询。让我知道这对您有用。

In your Listing relations method you need to have the relations to Users through the intermediate table UsersFavourite . 在您的Listing relations方法中,您需要通过中间表UsersFavouriteUsers建立关系。 The relationship type is HAS_MANY: 关系类型是HAS_MANY:

return array(
         'favourites'=>array(self::HAS_MANY, 'UserFavourite', 'listing_id'),
         'users'=>array(self::HAS_MANY, 'User', array('user_id'=>'id'), 'through'=>'favourites')
);

In your User method that returns the CActiveDataProvider : The main model is Listing , joined to UserFavourite and User . 在返回CActiveDataProviderUser方法中:主模型是Listing ,加入UserFavouriteUser You must set together to true to build one single sql query. 您必须设置together ,以true建立一个单一的SQL查询。 Finally you must set the users.id to the current id of User model to bring only the rows relevant to the current user. 最后,您必须将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')
));

I tested this answer and worked correctly with a small dataset. 我测试了这个答案,并使用一个小数据集正确工作。

Here is how I have achieved the required output: 这是我如何达到所需的输出:

$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,
));

In the end I have just hard-coded in the JOIN, rather than try and use the relation, as it seems it is not meant to work that way. 最后我在JOIN中进行了硬编码,而不是尝试使用关系,因为它似乎并不意味着以这种方式工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM