从 ActiveQuery->init() 覆盖条件
Override the condition from ActiveQuery->init()
在 Yii2 上,我在 ProjectQuery
中有这段代码
class ProjectQuery extends \yii\db\ActiveQuery
{
public function init()
{
$this->andOnCondition(['deleted' => 0]);
parent::init();
}
显然,已删除的条件必须始终适用,但在某些情况下可能并非如此(例如,用户可以选择查看已删除的项目)。我怎样才能覆盖这个条件?我必须使用不同于 init()
的东西吗?
(注意,我想将此条件正常应用于所有类型的查询,这就是为什么我在 ProjectQuery
上使用 init()
而不是 ProjectSearch
class)
您仍然可以使用 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();
您可以使用 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()
。
假设您有一个 class Project
,您已将 find()
方法覆盖为 return 一个 ProjectQuery
实例,以下可能是另一个选项。我还假设您经常查询未删除的项目,而不是经常查询 all/deleted 项目。
另一种选择是向 Project
class 添加另一种方法并删除 ProjectQuery
class.
中的默认初始化
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])
,这意味着找不到任何记录。但是,关于安全性,这并不是那么重要,我想问题很容易被发现。
在 Yii2 上,我在 ProjectQuery
class ProjectQuery extends \yii\db\ActiveQuery
{
public function init()
{
$this->andOnCondition(['deleted' => 0]);
parent::init();
}
显然,已删除的条件必须始终适用,但在某些情况下可能并非如此(例如,用户可以选择查看已删除的项目)。我怎样才能覆盖这个条件?我必须使用不同于 init()
的东西吗?
(注意,我想将此条件正常应用于所有类型的查询,这就是为什么我在 ProjectQuery
上使用 init()
而不是 ProjectSearch
class)
您仍然可以使用 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();
您可以使用 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()
。
假设您有一个 class Project
,您已将 find()
方法覆盖为 return 一个 ProjectQuery
实例,以下可能是另一个选项。我还假设您经常查询未删除的项目,而不是经常查询 all/deleted 项目。
另一种选择是向 Project
class 添加另一种方法并删除 ProjectQuery
class.
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])
,这意味着找不到任何记录。但是,关于安全性,这并不是那么重要,我想问题很容易被发现。