【问题标题】:Override the condition from ActiveQuery->init()覆盖 ActiveQuery->init() 中的条件
【发布时间】:2018-05-04 09:21:56
【问题描述】:

在 Yii2 我有这个代码在ProjectQuery

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

显然,已删除的条件必须始终适用,但在某些情况下可能不适用(例如,用户可以选择查看他已删除的项目)。我怎样才能覆盖这个条件?我必须使用与init() 不同的东西吗?

(注意,我想正常将此条件应用于所有类型的查询,这就是为什么我在ProjectQuery 上使用init() 而不是ProjectSearch 类)

【问题讨论】:

  • 为什么你使用andOnCondition()而不是andWhere()?
  • 因为它需要一个附加条件。

标签: yii yii2


【解决方案1】:

您仍然可以使用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();

【讨论】:

    【解决方案2】:

    您可以使用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()、andWhere和orWhere()添加的条件,你可以用同样的方式使用where()。

    【讨论】:

    • 是的,我已经使用了 includeDeleted() 函数。我的问题是,有没有办法声明 andOnCondition 所以如果有另一个条件 WHERE deleted = 1 的发现 init() andOnCondition 将被忽略?
    • 我不知道如何实现,但我会小心这种方法。我宁愿创建单独的模型(例如 AllPosts 和 Posts 用于未删除的模型)而不是依赖默认条件,有时应该覆盖它。
    【解决方案3】:

    假设您有一个 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]) 这意味着找不到任何记录。但是,关于安全性,这并不是那么重要,我想问题很容易被发现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-15
      • 1970-01-01
      • 2016-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多