Yii2 ActiveQuery:是否有可能将Where和Where结合在一起?

xtx*_*xtx 5 yii2

不确定标题是否完全描述了问题,无论如何这是情况:假设我有一个如下所示的ActiveQuery后代类:

class OrderQuery extends ActiveQuery
{
    public function expired() {
        $this->andWhere(['<=', 'order.expiresAt', date("Y-m-d H:i:s")]);
        return $this;
    }

    public function cancelled() {
        $this->andWhere(['NOT', ['order.cancelled' => null]]);
        return $this;
    }
}
Run Code Online (Sandbox Code Playgroud)

我想添加一个额外的方法archived()来查找已过期或已取消的订单.

public function archived() {
    $this->andWhere(["OR",
        ['<=', 'order.expiresAt', date("Y-m-d H:i:s")],
        ['NOT', ['order.cancelled' => null]],
    ]);
    return $this;
}
Run Code Online (Sandbox Code Playgroud)

上面的方法工作正常,但我想知道,是否可以在新的archived()方法中重用现有方法expired()和cancel()?


或者,换句话说,是否有可能结合使用和/或以某种方式使它们像这样一起工作:

// pseudocode, not a real code!
$this->orWhere([
    $this->andWhere([...]),
    $this->andWhere([...]),
]);
Run Code Online (Sandbox Code Playgroud)

谢谢!

rob*_*006 5

目前没有直接的方式来加入多个查询的条件.在GitHub上已经有一个功能请求,但它还没有实现.

目前您可以尝试2种解决方案:

  1. 如果您不想重复条件,可以为它们创建帮助:

    private function getExpiredContition() {
        return ['<=', 'order.expiresAt', date('Y-m-d H:i:s')];
    }
    
    private function getCancelledContition() {
        return ['NOT', ['order.cancelled' => null]];
    }
    
    public function expired() {
        return $this->andWhere($this->getExpiredContition());
    }
    
    public function cancelled() {
        return $this->andWhere($this->getCancelledContition());
    }
    
    public function archived() {
        return $this->andWhere([
            'OR',
            $this->getExpiredContition(),
            $this->getExpiredContition(),
        ]);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 您可以尝试$where直接访问属性并将其合并到一个查询中.

    public function archived() {
        return $this->andWhere([
            'OR',
            (new static())->cancelled()->where,
            (new static())->expired()->where,
        ]);
    }
    
    Run Code Online (Sandbox Code Playgroud)


Yer*_*rke 5

$this->orWhere([
    $this->andWhere([...]),
    $this->andWhere([...]),
]);
Run Code Online (Sandbox Code Playgroud)

我担心没有办法where()在其他where()函数中使用函数.Yii2根本就不是这样设计的..这将是可能的,如果Yii2 where(),orWhere(),andWhere()功能获得了闭包,喜欢做joinWith(),with()等的方法(接收匿名函数嵌套模型查询).

你可以把关闭放在Laravel的条件下(非主题)

我想,作为一种解决方法,您可以创建私有方法并以数组格式返回这些条件,如下所示:

class OrderQuery extends ActiveQuery
{
    private function conditionExpired() {
        return ['<=', 'order.expiresAt', date("Y-m-d H:i:s")];
    }

    private function conditionCancelled() {
        return ['NOT', ['order.cancelled' => null]];
    }

    public function expired() {
        $this->andWhere($this->conditionExpired());
        return $this;
    }

    public function cancelled() {
        $this->andWhere($this->conditionCancelled());
        return $this;
    }

    public function archived() {
        $this->andWhere(["OR",
            $this->conditionExpired(),
            $this->conditionCancelled(),
        ]);
        return $this;
    }
}
Run Code Online (Sandbox Code Playgroud)