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

时间:2018-04-20 09:23:20

标签: 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;
    }
}

我想添加其他方法 archived(),以查找已过期或已取消的订单。

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

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

或者,换句话说,是否可以将andWhere和orWhere结合起来 不知怎的,让他们像这样一起工作:

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

谢谢!

2 个答案:

答案 0 :(得分:5)

目前没有直接的方式来加入多个查询的条件。在GitHub上已经存在feature request,但尚未实现。

目前您可以尝试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(),
        ]);
    }
    
  2. 您可以尝试直接访问$where属性并将其合并到一个查询中。

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

答案 1 :(得分:5)

$this->orWhere([
    $this->andWhere([...]),
    $this->andWhere([...]),
]);

我担心无法在其他where()函数中使用where()函数。 Yii2根本就不是那样设计的......如果Yii2 where()orWhere()andWhere()函数收到一个闭包,就像在joinWith()中那样,{{1方法(在匿名函数中接收嵌套模型查询)。

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

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

with()