YiiFramework JOIN + условие по умолчанию

grigori

( ͡° ͜ʖ ͡°)
Команда форума
при работе с фреймворком надо начинать с прочтения официальной документации, статьи на странных сайтах не помогут

в Active Record join-ы реализуют отношения таблиц - связи
а в query builder просто join()
 

StalkerClasses

Новичок
Вот пример из данных ссылок:
$query->join('LEFT JOIN', 'post', 'post.user_id = user.id');

Присоединяется post - а если данный пост выключен (удален в корзину)?
В Active records через find при выборке постов автоматически добавляется del = 0.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
нет в статьях по ссылкам никакой корзины, и никакое условние в ActiveRecord автоматически не добавляется, ты разговариваешь сам с собой
 

StalkerClasses

Новичок
Изучил работу на примере вот этих трех функций:
PHP:
        // with()
        // joinWith() - используется когда нужно фильтровать или искать данные в связанных таблицах
        // InnerJoinWith() - возвращает данные если есть связь между полями
Все они добавляют то необходимое условие и по основной find() модели и по присоединяемой with() модели.
В интернете все делают условия по умолчанию через переопределение метода find() в модели.

Мне не совсем подходит этот метод, т.к. мне нужно добавить условия по умолчанию когда уже весь запрос сформирован и с учетом того, что за таблицы задействованы в нем:
PHP:
BlogCategory::find()->alias('table1')->where(['table1.id'=>2])->InnerJoinWith('parent AS alias')->InnerJoinWith('element AS alias2')->asArray()->all();
Т.е. все добавляют условия по умолчанию еще на этапе формирования "BlogCategory::find()".
Мне же нужно добавить условия в конце когда уже запрос сформирован когда уже знаешь какие таблицы в запросе задействованы.
Нашел способ через переопределение метода "ActiveQuery"
PHP:
    public function createCommand($db = null)
    {
        $command = parent::createCommand($db);
        $this->myCondition();
        return $command;
    }
Но есть одна проблема - мне нужно получить список таблиц и алиасов к ним, которые участвуют в запросе.
И это смог бы реализовать переопределив также функции как и public function createCommand
PHP:
private function quoteTableNames($tables, &$params){} // возврящет АЛИАС + ТАБЛИЦА
private function getTableNameAndAlias(){} // возврящет АЛИАС + ТАБЛИЦА
Но проблема в том, что это private методы.
Как можно после формирования запроса получить список всех таблиц участвующих в запросе и алиасов к ним?
 

StalkerClasses

Новичок
Сформулирую вопрос проще - как после формирования запроса получить список таблиц которые участвуют в этом запросе и алиасов к ним?
Кстати - давно не был на форуме phpclub - классный движок и темы поставили😀 .
PHP:
    public function createCommand($db = null)
    {
        $command = parent::createCommand($db);
        $table_all = [];
        if(!empty($this->from)){
            foreach($this->from as $alias => $tablename){
                if(is_integer($alias)){
                    $table_all[$tablename] = $tablename;
                } else {
                    $table_all[$alias] = $tablename;
                }
            }
        }else{
            $model = $this->modelClass;
            $tablename = $model::tableName();
            $tablename = str_replace('{{','',$tablename);
            $tablename = str_replace('}}','',$tablename);
            $table_all[$tablename] = $tablename;
        }
        if(!empty($this->join)){
            foreach($this->join as $joinKey => $joinValue){
                if(is_array($joinValue[1])){
                    foreach($joinValue[1] as $alias => $tablename){
                        if(is_integer($alias)){
                            $table_all[$tablename] = $tablename;
                        } else {
                            $table_all[$alias] = $tablename;
                        }
                    }
                }else{
                    $table_all[$joinValue[1]] = $joinValue[1];
                }
            }
        }
        if(count($table_all)>0){
            foreach($table_all as $alias => $tablename){
                $this->enableFields($tablename, $alias); // то самое необходимое условие!
            }
        }
        $command = parent::createCommand($db);
        return $command;
    }
 
Последнее редактирование:

grigori

( ͡° ͜ʖ ͡°)
Команда форума
1. sql-запрос формируется в самый последний момент, в твоем примере - при вызове asArray(),
хотеть чего-то, когда запрос сформирован - бессмысленно, это так не работает
2. чтобы получить список таблиц - надо прочитать структуру в объекте Command, но делать так - неправильный алгоритм
3. условия по умолчанию - это то, что добавляется в запрос перед кастомными параметрами, а не после
4. то. что ты делаешь, обычно делаются на Query Builder без автосгенерированных классов

короче, ты что-то там себе придумал, пытаешься надеть штаны на голову, а они не держатся
 

StalkerClasses

Новичок
У вас в каждой таблице есть поле del (запись не активна).
Делаете запрос с участием трех таблиц (первая from, вторая и третья join или with) - каждой будете руками писать del=0 del=0 del=0? А потом еще раз и много много раз.

Сейчас делая запрос вида:

PHP:
$model_r = BlogSetting::find()->alias('table1')->InnerJoinWith('blog')->where(['>','table1.id',0])->asArray()->all();
У меня и BlogSetting будет del=0
И то что в InnerJoinWith() тоже будет с del=0
Заранее нет возможности определить какое кол-во join или with() будет в запросе. Оно известно только уже перед all().
 
Последнее редактирование:

grigori

( ͡° ͜ʖ ͡°)
Команда форума
У вас в каждой таблице есть поле del (запись не активна).
Делаете запрос с участием трех таблиц (первая from, вторая и третья join или with) - каждой будете руками писать del=0 del=0 del=0? А потом еще раз и много много раз.
три раза напишу, на четвертый отрефакторю, и буду использовать это в остальных местах
если решать задачу костылем в коде, который был создан для других задач - затраты времени на такое решения непредсказуемы, и могут занять сколько угодно времени - буквально, месяцы
 

StalkerClasses

Новичок
Суть проблемы была описана в самом начале. Ниже я также описал как смог решить данную непростую задачу. Если есть более изящные решение - его в ответах ждал, но судя по всему его нет.
 

StalkerClasses

Новичок
Любая из моих созданных моделей (таблиц) может содержать ряд дефолтовых настроек:
- версия записи
- локализация
- включена/выключена (флаг)
- удалена в корзину (флаг)
- запись только для внутреннего пользователя (флаг)
- доступ во внешнем интерфейсе (в зависимости от группы пользователя)
- начало/окончание активности
- ряд других специфичных параметров.

Мне все это нужно что бы yii2 учитывал при выборке в зависимости от того что определено в настройках модели (таблицы) при использовании конструктора запросов.

Решение нашёл - выше пример дал. В yii1 кстати это по-моему было реализовано.
 
Сверху