yii 覆盖ActiveQuery->init()中的条件

uelo1irk  于 2022-11-09  发布在  其他
关注(0)|答案(3)|浏览(120)

在Yii2上,我在ProjectQuery中有此代码

class ProjectQuery extends \yii\db\ActiveQuery
{
    public function init()
    {
        $this->andOnCondition(['deleted' => 0]);
        parent::init();
    }

显然,删除的条件必须始终适用,但也有可能不适用(例如,用户可以查看已删除项目的选项)。如何覆盖此条件?是否必须使用不同于init()的内容?
(note,我希望将此条件应用于所有类型的查询,这就是为什么我在ProjectQuery上使用init()而不是ProjectSearch类的原因)

emeijp43

emeijp431#

您仍然可以使用init(),但是要覆盖0,您应该绑定一个参数。

public function init()
{
    $this->andOnCondition('deleted = :deleted', [':deleted' => 0]);
    parent::init();
}

因此,要创建一个只显示已删除项目的查询,请编写如下代码:

$query = Project::find()->addParams([':deleted' => 1]);

要显示所有已删除和未删除的项目,您可以向ProjectQuery对象添加一个函数,以相应地修改它。

public function includeDeleted() {
    $this->orOnCondition(['deleted' => 1]);
    return $this;
}

然后编写如下查询:

$query = Project::find()->includeDeleted();
c9x0cxw0

c9x0cxw02#

您可以使用onCondition()来覆写现有的on条件:

public function init() {
    $this->andOnCondition('deleted = :deleted', [':deleted' => 0]);
    parent::init();
}

public function includeDeleted() {
    $this->onCondition(null);
    // remove unused param from old ON condition
    unset($this->params[':deleted']);

    return $this;
}

如果要覆盖由where()andWhereorWhere()添加的条件,则可以以相同的方式使用where()

j7dteeu8

j7dteeu83#

假设您有一个类Project,其中您已经覆盖了find()方法以返回一个ProjectQuery示例,下面可能是另一种选择。我还假设您经常查询未删除的项,并且不是经常查询,而是显式查询所有/已删除的项。
另一个选择是将另一个方法添加到Project类中,并删除ProjectQuery类中的默认初始化。

class ProjectQuery extends \yii\db\ActiveQuery
{
    public function init()
    {
        parent::init();
    }
    ...
}

还有:

class Project extends \yii\db\ActiveRecord {
    ...
    public static function find()
    {
        return (new ProjectQuery(get_called_class()))
               ->andOnCondition(['deleted' => 0]);
    }

    public static function findAllProjects() // or find any better name for this
    {
        return new ProjectQuery(get_called_class());
    }
}

现在,无论何时你想显式查询所有项目,你都需要使用这个额外的方法Project::findAllProjects()。所以在正常情况下,你不必记住你必须以某种方式修改查询。没有危险,这可能会被忘记。
它仍然不是100%令人满意的,因为可以使用find()并添加->andOnCondition(['deleted' => 1]),这意味着找不到记录。但是,关于安全性,这不是那么关键,我想问题很容易被发现。

相关问题