无法在Yii2中对HasMany关系进行排序

时间:2019-05-02 08:48:57

标签: php yii2

我知道有关Yii2中排序属性的问题很多。我是使用此框架的初学者,并且已经用尽了所有可以在Internet上找到的参考。

因此,第一部分。

我尝试在Controller上使用orderBy方法,但似乎也不起作用。

我的控制器部分使用以下代码:

$saleModel = Sales::find()->with([
    'customer',
    'salesItems',
    'salesItems.item'
])->where(['id' => $id])->one();

现在我有一个名为Sales的模型,该模型与SalesItems模型具有hasMany关系。

public function getSalesItems()
{
    return $this->hasMany(SalesItems::className(), ['sale_id' => 'id'])
}

我尝试使用可以在此模型中找到的“ item_id”对该SalesItems模型进行排序,并且该模型正在运行。

public function getSalesItems()
{
    return $this->hasMany(SalesItems::className(), ['sale_id' => 'id'])
        ->orderBy(['item_id' => SORT_DESC]);
}

但是我想要通过通过销售项目模型中的item_id列连接的另一个已连接表/模型对我的SalesItems进行排序。

在这种情况下,我还有另一个表,称为item,其中有一个ID列,这部分是它们连接['id' =>'item_id']的地方。

总体而言,我想基于items.name对我的SalesItems进行排序。

我的SQL语句应如下所示:

SELECT sales.id , sales.customer_id, sales_items.item_id, 
sales_items.sale_id, items.name FROM sales
INNER JOiN sales_items ON sales_items.sale_id = sales.id
INNER JOIN items ON sales_items.item_id = items.id WHERE sales.id =6374
ORDER BY items.name ASC;

我在数据库上运行此SQL Statemend,并按照我想要的方式成功检索了结果。

这也是表Schema:

enter image description here

希望有人可以理解我一直在尝试做的事情。

谢谢

5 个答案:

答案 0 :(得分:0)

您需要对joinWith使用以下查询来实现所需的功能,还需要在列表中再选择一列i.id,否则它只会显示一项。

$saleModel = Sales::find()->alias('s')
    ->select('s.id, s.customer_id, si.item_id, si.sale_id, i.name, i.id')
    ->joinWith(
        [
            'customer c',
            'salesItems si',
            'salesItems.item i'
        ], false, 'INNER JOIN'
    )
    ->where(['s.id' => 1])->orderBy('i.name ASC')->asArray()->all();

答案 1 :(得分:0)

您可以尝试使用ActiveQuery的viaTable函数:

public function getSalesItems()
{
    return $this->hasMany(SalesItems::className(), ['sale_id' => 'id'])
         ->viaTable('items', ['id' => 'item_id'])
         ->orderBy(['items.name' => SORT_ASC]);
}

答案 2 :(得分:0)

尝试这些代码(它们已经在我的本地主机上工作了):

在控制器中:

$sales = Sales::find()->with([
            'customer',
            'salesItems',
            'salesItems.item'
        ])->where(['id' => 2])->asArray()->one();

$db = Yii::$app->db;

        $query = $db->createCommand("SELECT sales.id , sales.customer_id, sales_items.item_id, 
                    sales_items.sale_id, items.name FROM sales
                    INNER JOiN sales_items ON sales_items.sale_id = sales.id
                    INNER JOIN items ON sales_items.item_id = items.id WHERE sales.id =2
                    ORDER BY items.name ASC;")->queryAll();

在SalesItems模型中:

<?php
//...
class SalesItems extends \yii\db\ActiveRecord
{
//...
public function getItem()
    {
        return $this->hasOne(Items::className(), ['id' => 'item_id']);
    }
//...
}

在销售模式中:

<?php
//...
class Sales extends \yii\db\ActiveRecord
//...
public function getSalesItems()
    {
        return $this->hasMany(SalesItems::className(), ['sale_id' => 'id'])->orderBy(['item_id' => SORT_DESC]);
    }

    public function getCustomer()
    {
        return $this->hasOne(Customers::className(), ['id' => 'customer_id']);
    }
// ...
}

答案 3 :(得分:0)

使用活动记录:

     $query = Sales::find()->alias('sl')
        ->select('sl.id, sl.customer_id, si.item_id, si.sale_id, itm.name')
        ->joinWith('salesItem AS si', true)
        ->joinwith('salesItem.item AS itm')
        ->where(['si.id' => $id])
        ->orderBy(['itm.name' => SORT_ASC]);   

然后,您可以使用提供的任何方法来检索查询结果。或者,如果您想测试查询,请使用:

$sql = $query->createCommand()->sql; 

查看它是否与原始查询匹配。

答案 4 :(得分:0)

除了laravel之外,我很少在大多数框架中使用关系功能。

了解您的问题和提出的ERD之后,我将针对此特定问题建议简化的答案

我注意到 si.sale_id 加入了 s.id ,因此在数字上保持关系不变

因此,这是我的首选解决方案

/**
 * 
 * @param integer $sales_id sales id
 * @return \frontend\models\SalesItems[] models
 */
public function getSalesItems($sales_id) {

    $s = \frontend\models\Sales::tableName();

    $si = \frontend\models\SalesItems::tableName();

    $i = \frontend\models\Items::tableName();

    return $this
                ->select('s.id, s.customer_id, si.item_id, si.sale_id, i.name')->from("$si si")
                ->leftJoin("$s s", "'$sales_id' = s.id")
                ->leftJoin("$i i", "si.item_id = i.id")
                ->where("si.sale_id = '$sales_id'")
                ->orderBy('i.name asc')
                ->all();
}

在SalesItems模型类中运行此

请仅在 SalesItems 模型类中引入以下两个属性(而不是数据库表表)

class SalesItems extends \yii\db\ActiveRecord {

    // copy line below into SalesItems class
    public $name, $customer_id;

}

我相信它是通过这种方式高度优化的

希望有帮助

谢谢