在Yii2中重用查询速记时如何避免模糊字段?

时间:2015-06-15 07:08:01

标签: php mysql yii2

我有如下表格。

CREATE TABLE A (
    id INT,
    relationId INT,
    status INT
)


CREATE TABLE B (
    id INT,
    status INT
)

类文件如下所示

class A extends \yii\db\ActiveRecord {
    public function getB() {
        return $this->hasOne(B::class, ['id' => 'relationId']);
    }

    public function find() {
        return new AQuery(__CLASS__);
    }
}

class AQuery extends \yii\db\Query {
    public function isActive() {
        return $this->andWhere(['status' => 1]);
    }
    public function isNotActive() {
        return $this->andWhere(['status' => 0]);
    }
}

class B extends \yii\db\ActiveRecord {
    public function find() {
        return new BQuery(__CLASS__);
    }
}

class BQuery extends \yii\db\Query {
    public function isActive() {
        return $this->andWhere(['status' => 1]);
    }
    public function isNotActive() {
        return $this->andWhere(['status' => 0]);
    }
}

我正在做这样的事情

$model = A::find()
            ->joinWith([
                'b' => function(BQuery $query) {
                     $query->isNotActive();
                }
            ])
            ->isActive()
            ->one();

这会产生错误

Column 'status' in where clause is ambiguous"

我知道的唯一方法是手动将别名添加到$query->from并重写$query->andWhere。但有没有更简单的方法来重用查询速记?

2 个答案:

答案 0 :(得分:1)

使用ActiveRecord::tableName()代替别名(它似乎不是Yii2中的有效记录功能)。可以通过tableName()的{​​{3}}属性访问\yii\db\ActiveQuery

public function isActive() {
    $modelClass = $this->modelClass;
    return $this->andWhere([$modelClass::tableName().'.status' => 1]);
}

答案 1 :(得分:0)

您可以使用optionnal参数增强isActive()方法以接受别名。你可以尝试这样的事情:

class AQuery extends \yii\db\Query {
    protected function getAlias($alias = null) {
        return $alias !== null ? $alias : A::tableName();
    }

    public function isActive($alias = null) {
        $alias = $this->getAlias($alias);
        return $this->andWhere(["{$alias}.status" => 1]);
    }

    public function isNotActive($alias = null) {
        $alias = $this->getAlias($alias);
        return $this->andWhere(["{$alias}.status" => 0]);
    }
}