samdark / yii2-cookbook

Yii 2.0 Community Cookbook
1.44k stars 297 forks source link

Дублируется метод prepare() #84

Closed evgenmil closed 8 years ago

evgenmil commented 8 years ago

Здравствуйте. Подскажите, пожалуйста, может конечно, я что-то делаю не так. Делаю простое наследование модели по типу (по категории товара).

namespace app\models;
use app\models\query\GoodPhoneQuery;

class GoodPhone extends GoodItems
{
    /**
     * @inheritdoc
     * @return \app\models\query\GoodPhoneQuery the active query used by this AR class.
     */
    public static function find()
    {
        return new GoodPhoneQuery(get_called_class());
    }
}

app\models\query\GoodPhoneQuery :

namespace app\models\query;
use yii\db\ActiveQuery;

class GoodPhoneQuery extends ActiveQuery
{
    public function prepare($builder)
    {
        $this->distinct();
        $this->joinWith('goods.category');
        $this->andWhere('ix_category_goods = 74'); // категория товара хранится в таблице category
        return parent::prepare($builder);
    }
}

Делаю запрос:

public function actionSelectPhone()
    {
        $query = GoodPhone::find();
        VarDumper::dump($query->count(), 3, true);
    }

Появляется исключение SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'goods'. Вывел sql через getRawSql() понял, что метод prepare() отработал два раза. В чем может быть причина? и правильно ли я делаю? Заранее благодарю!

samdark commented 8 years ago

Который из них отработал два раза?

evgenmil commented 8 years ago

Оба метода:

$this->joinWith('goods.category');
$this->andWhere('ix_category_goods = 74');

отработали два раза, т.е. присутствуют в итоговом SQL-запросе.

samdark commented 8 years ago

Что-то тут не так... не должен сам по себе prepare вызываться два раза.

evgenmil commented 8 years ago

Согласен. Когда вызываю метод all(), то все в порядке. Отрабатывает, как нужно. Такое случается только при вызове метода count(). Здесь https://github.com/yiisoft/yii2/blob/master/framework/db/Query.php#L391 метод prepare() отрабатывает второй раз и срабатывает исключение.

samdark commented 8 years ago

Сесть и разобраться пока не могу. Кидайте в gitter или на форумы. О результатах отпишитесь здесь.

samdark commented 8 years ago

Issue пока закрыл так как собственно к кукбуку отношения не имеет.