Повторяющуюся таблица, activerecod init

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
iamguruman
Сообщения: 236
Зарегистрирован: 2018.05.10, 08:26

Повторяющуюся таблица, activerecod init

Сообщение iamguruman »

Каждый раз сталкиваюсь вот с такого рода структурой и не знаю как победить ошибку "Повторяющася таблица"

Код: Выделить всё


Class User extends ActiveRecord {
     tableName: user

   public function getLocation(){
      this->hasOne([Location=> ['id' => 'location_id']])
   }
}

// таблица с иерархией, в таблице колонка location.parent_location_id связана с location.id
Class Location extends ActiveRecord {
     tableName: location

   public function getParent(){
      this->hasOne([Location => ['id' => 'parent_location_id']])
   }
}

// удалять "области" нельзя, нужно их скрывать, по умолчанию они скрыты через инит
Class LocationQuery extends ActiveQuery {

   init(){
   	return this->andWhere['location.deleted' => null];
   }
}

Class UserSearch extends User {
     tableName: location

   public $locationParentSearchName;
   
   rules {[['locationParentSearchName', 'string']]}
   
   search(){
     if(!empty($this->locationParentSearchName)){
     	$quaery->joinWith('location.parent')->andWhere(['like', 'name', $this->locationParentSearchName]);
     }
   }
}

в результате примерно такой запрос в базе:

Код: Выделить всё

SELECT * FROM `user` 
LEFT JOIN `location` ON `user`.`location_id` = `location`.`id` 
LEFT JOIN `location` ON `location`.`parent_location_id` = `location`.`id` 
WHERE 
(`user`.`deleted` IS NULL) 
AND 
(`name` LIKE '%область%') 
AND
((`location`.`deleted` IS NULL) 
AND 
((`location`.`deleted` IS NULL) 
Повторяющаяся таблица/псевдоним 'location'

Два раза location появляется в запросе, потому что:
1) делаем первый вход в таблицу location и у нее стоит init в котором есть условие location.deleted => null
и затем щаг 2) делаем вход в таблицу location через parent_location_id и снова отрабатывает инит и выводит в запрос location.deleted => null

3) потенциально вижу проблему с location.name, потому что у меня их два... видимо если победить проблему с таблицей/псведонимом, то появится новая с не уникальностью name (таблица location)

посоветуйте, пожалуйста
duda
Сообщения: 43
Зарегистрирован: 2015.07.06, 22:05

Re: Повторяющуюся таблица, activerecod init

Сообщение duda »

LEFT JOIN `location` as 'location_one'
LEFT JOIN `location` as 'location_two
....

AND
((`location_one`.`deleted` IS NULL)
AND
((`location_two`.`deleted` IS NULL)
iamguruman
Сообщения: 236
Зарегистрирован: 2018.05.10, 08:26

Re: Повторяющуюся таблица, activerecod init

Сообщение iamguruman »

unknownby писал(а): 2021.06.25, 07:56 Использовать алиасы для связей пробовали?
да, пробовал, но при этом в инит они не срабатывают (ошибку выдает, потому что название алиаса не определяет)... ведь получается в алиасе эта таблица участвует несколько раз... но я так понимаю не реализовано подставлять наименование алиаса при работе инита
iamguruman
Сообщения: 236
Зарегистрирован: 2018.05.10, 08:26

Re: Повторяющуюся таблица, activerecod init

Сообщение iamguruman »

duda писал(а): 2021.06.25, 13:53 LEFT JOIN `location` as 'location_one'
LEFT JOIN `location` as 'location_two
....

AND
((`location_one`.`deleted` IS NULL)
AND
((`location_two`.`deleted` IS NULL)
это то понятно, но это скл, а хочется через активрекорд
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Повторяющуюся таблица, activerecod init

Сообщение unknownby »

iamguruman писал(а): 2021.06.26, 00:04
unknownby писал(а): 2021.06.25, 07:56 Использовать алиасы для связей пробовали?
да, пробовал, но при этом в инит они не срабатывают (ошибку выдает, потому что название алиаса не определяет)... ведь получается в алиасе эта таблица участвует несколько раз... но я так понимаю не реализовано подставлять наименование алиаса при работе инита
А если убрать location? Тоже не работает?

Код: Выделить всё

Class LocationQuery extends ActiveQuery {

   init(){
   	return this->andWhere['deleted' => null];
   }
}
алиасы в связях

Код: Выделить всё

public function getLocation(){
      this->hasOne([Location=> ['id' => 'location_id']])->alias('loc');
   }
public function getParent(){
      this->hasOne([Location => ['id' => 'parent_location_id']])->alias('loc_p');
   }
В противном случае и не самом хорошем, нужно будет это условие добавить в каждую связь и не использовать LocationQuery
Ответить