Yii2 过滤具有多重关系的数据

Posted

技术标签:

【中文标题】Yii2 过滤具有多重关系的数据【英文标题】:Yii2 Filter data with multiple relation 【发布时间】:2019-02-06 05:10:14 【问题描述】:

我正在制作和列出船只有两种类型的船只页面

共享。 私人。

如果有共享船只

我必须检查

如果他们提供半天 (1/2) 行程,则显示半天价格。 如果半天不可用,请检查是否为一天的四分之三 (3/4),价格是否为一天的四分之三。 否则检查全天并获取全天价格。

如果共享船不可用

检查是否有可用的私人船只。 然后对私人船只应用上面给出的相同方案。

对于这些定价,我使用了条件,但在过滤从高到低/从低到高的价格过滤时,我不知道如何应用条件。有人可以帮我解决这些问题。

型号:

Boatinformation(Main).

Boatsharedfishingtrip(shared pricing)

Boatfishingcharter(Private Pricing)

模型关系:

public function getBoatfishingcharter() 
    return $this->hasOne(Boatfishingcharter::className(), ['boat_id' => 'boat_id']);


public function getBoatsharedtrip() 
    return $this->hasOne(Boatsharedfishingtrip::className(), ['boat_id' => 'boat_id']);


if($model->boatsharedtrip->shared_fishing_charters == '1') 
    if($model->boatsharedtrip->one_two_day_4hrs == 1) 
        $shared_price = $model->boatsharedtrip->one_two_day_rate_per_angler;
     else if($model->boatsharedtrip->three_four_day_6hrs == 1) 
        $shared_price = $model->boatsharedtrip->three_four_day_rate_per_angler;
     else if($model->boatsharedtrip->full_day_8hrs == 1) 
        $shared_price = $model->boatsharedtrip->full_day_rate_per_angler;
    
 else if($model->boatfishingcharter->private_fishing_charters == 1) 

    if($model->boatfishingcharter->one_two_day_4hrs == 1) 
        $private_price = $model->boatfishingcharter->one_two_day_rate;
     else if($model->boatfishingcharter->three_four_day_6hrs == 1) 
        $private_price = $model->boatfishingcharter->three_four_day_rate;
     else if($model->boatfishingcharter->full_day_8hrs == 1) 
        $private_price = $model->boatfishingcharter->full_day_rate;
    

对于我目前使用的过滤器:

if($_GET['orderby'] == 'price_desc') 
    $query->orderBy(['one_two_day_rate_per_angler' => SORT_DESC, 'one_two_day_rate' => SORT_DESC, 'three_four_day_rate_per_angler' => SORT_DESC, 'three_four_day_rate' => SORT_DESC, 'full_day_rate_per_angler' => SORT_DESC, 'full_day_rate' => SORT_DESC]);
 elseif($_GET['orderby'] == 'price_asc') 
    $query->orderBy(['one_two_day_rate_per_angler' => SORT_ASC, 'one_two_day_rate' => SORT_ASC, 'three_four_day_rate_per_angler' => SORT_ASC, 'three_four_day_rate' => SORT_ASC, 'full_day_rate_per_angler' => SORT_ASC, 'full_day_rate' => SORT_ASC]);



$query = Boatinformation::find();
        $query->leftJoin('boatsharedfishingtrip', '`boatsharedfishingtrip`.`boat_id` = `boatinformation`.`boat_id`')
              ->leftJoin('rating_review', '`rating_review`.`boat_id` = `boatinformation`.`boat_id`')
              ->leftJoin('boatotherservice', '`boatotherservice`.`boat_id` = `boatinformation`.`boat_id`')
              ->leftJoin('boatfishingequipment', '`boatfishingequipment`.`boat_id` = `boatinformation`.`boat_id`')
              ->join('INNER JOIN','boatcompanyinformation', '`boatcompanyinformation`.`id` = `boatinformation`.`boat_id`')
              ->leftJoin('boatfishingcharter', '`boatfishingcharter`.`boat_id` = `boatinformation`.`boat_id`')
              ->where(['boat_publish' => 1])->all();

编辑

这就是我在列表中显示船只的方式

【问题讨论】:

当您说您正在处理列表页面时,您是否使用GridView 来显示列表? 不,我在前端工作,不使用网格视图 你应该添加你正在处理的视图,为什么不添加 GridView 如果列表的布局将类似于 GridView 它可以减少 html 布局修复的大量工作 我通过列表添加了图片。我有许多其他正在工作的功能。我不能使用网格视图 您在计算之前对查询进行了排序,这将不起作用。一种解决方案是您从查询构建数组,然后可能使用usort() 对计算字段应用过滤器 【参考方案1】:

我是否正确理解表之间的关系类型是“一对一”? 我的意思是 Boatinformation、Boatsharedfishingtrip 和 Boatfishingcharter?

试试这个。

// Main query
$query = Boatinformation::find()
    ->leftJoin('boatsharedfishingtrip', '`boatsharedfishingtrip`.`boat_id` = `boatinformation`.`boat_id`')
    ->leftJoin('rating_review', '`rating_review`.`boat_id` = `boatinformation`.`boat_id`')
    ->leftJoin('boatotherservice', '`boatotherservice`.`boat_id` = `boatinformation`.`boat_id`')
    ->leftJoin('boatfishingequipment', '`boatfishingequipment`.`boat_id` = `boatinformation`.`boat_id`')
    ->join('INNER JOIN', 'boatcompanyinformation', '`boatcompanyinformation`.`id` = `boatinformation`.`boat_id`')
    ->leftJoin('boatfishingcharter', '`boatfishingcharter`.`boat_id` = `boatinformation`.`boat_id`')
    ->where(['boat_publish' => 1]);


// Sort
$orderBy = Yii::$app->request->get('orderby');

switch ($orderBy) 
    case 'price_desc':
        $query->orderBy(['one_two_day_rate_per_angler' => SORT_DESC, 'one_two_day_rate' => SORT_DESC, 'three_four_day_rate_per_angler' => SORT_DESC, 'three_four_day_rate' => SORT_DESC, 'full_day_rate_per_angler' => SORT_DESC, 'full_day_rate' => SORT_DESC]);
        break;

    case 'price_asc':
        $query->orderBy(['one_two_day_rate_per_angler' => SORT_ASC, 'one_two_day_rate' => SORT_ASC, 'three_four_day_rate_per_angler' => SORT_ASC, 'three_four_day_rate' => SORT_ASC, 'full_day_rate_per_angler' => SORT_ASC, 'full_day_rate' => SORT_ASC]);
        break;



// Execute
// var_dump( $query->createCommand()->getRawSql() );  // Uncomment to debug built SQL

$query->all();

你在使用 Yii2 调试工具栏吗?如果是这样,请在此处复制粘贴构建 SQL。 如果不是,请取消注释 getRawSql 行。它可能有助于弄清楚为什么它不适合您。

【讨论】:

我读了你的问题。但首先,我试图猜测你是如何解决这个问题的。因为你的代码不正确,无论如何它都不起作用。 @JankiRathod 如果我正确理解了您的问题,您正在尝试使用 php 计算“总价”。这种方法确实允许使用 mysql 进行过滤。这种情况有两种方法: 1)你可以为这个价格建立SQL表达式,并用它来过滤和排序。 2) 您可以将所有必要的记录加载到 PHP,计算所有价格,准备 ArrayDataProvider,并使用 Pager 显示它。机器人方式可以很好地过滤、分页和排序,但第二种方式需要更多的内存和 CPU 时间。

以上是关于Yii2 过滤具有多重关系的数据的主要内容,如果未能解决你的问题,请参考以下文章

yii2 多重过滤器进入搜索模型

具有逗号的多重过滤的数据表

Yii 2:同一张表的多重关系

Yii2 Select2 使用 ajax 多重:非法偏移类型

Yii2 和 reactjs CORS 过滤器给出错误:预检响应具有无效的 HTTP 状态代码 401

从具有多对多关系 django 的两个表中过滤数据