Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
an.viktory@gmail.com
Сообщения: 536 Зарегистрирован: 2016.09.05, 23:21
Сообщение
an.viktory@gmail.com » 2018.03.12, 18:56
собственно вопрос, будет ли нормально работать связь при withJOIN если я сделаю так:
Код: Выделить всё
public function getOnControls()
{
return $this->hasOne(SaleFiltersOnControl::className(), ['salefilter_id' => 'id'])->andWhere(['id_street' => 'id_street']);
}
или мне использовать еще одну связь
andku83
Сообщения: 988 Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков
Сообщение
andku83 » 2018.03.12, 19:16
в большинстве случаев будет работать, andWhere перенесется в внешний WHERE запроса
чтобы не переносился его можно заменить на onCondition([])
an.viktory@gmail.com
Сообщения: 536 Зарегистрирован: 2016.09.05, 23:21
Сообщение
an.viktory@gmail.com » 2018.03.12, 20:34
желательно чтобы работало во всех случаях)))
Код: Выделить всё
$this->from(['s' => Sale::tableName()]);
$this->joinWith(['controls AS controls']);
public function getControls()
{
return $this->hasOne(SaleFiltersOnControl::className(), ['id_street => 'id_street])
->onCondition(['controls.id_salefilter' => Yii::$app->params['id_salefilter']]);
}
при построении query будет условие
Код: Выделить всё
$query->andWhere(['<=','s.price', 'controls.price']);
в данном случае будет работать ?
andku83
Сообщения: 988 Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков
Сообщение
andku83 » 2018.03.12, 23:18
по идее должно, только по-моему не совсем правильно вы написали
Код: Выделить всё
->andOnCondition(['id_similar' => new \yii\db\Expression('s.id_similar')])
и в Where с price тоже нужно последний аргумент так обернуть
an.viktory@gmail.com
Сообщения: 536 Зарегистрирован: 2016.09.05, 23:21
Сообщение
an.viktory@gmail.com » 2018.03.13, 00:05
извиняюсь но вообще в начале все не так сделал, предыдущий мой пост переписал
остается только вопрос эстетики: как при объявлении связи передавать переменную (а неглобально как я передал).
andku83
Сообщения: 988 Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков
Сообщение
andku83 » 2018.03.13, 00:24
убрать из связи ограничение и применять его только тогда когда нужно:
Код: Выделить всё
$query->joinWith([
'controls' => function ($query) use ($param) {
$query->onCondition(['controls.id_salefilter' => $param]);
}
]);
andku83
Сообщения: 988 Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков
Сообщение
andku83 » 2018.03.13, 00:43
hasOne со всем его содержимым остался в связи, или он тоже должен конфигурироваться?
an.viktory@gmail.com
Сообщения: 536 Зарегистрирован: 2016.09.05, 23:21
Сообщение
an.viktory@gmail.com » 2018.03.13, 00:54
т.е. связь вот такая
Код: Выделить всё
public function getControls()
{
return $this->hasOne(SaleFiltersOnControl::className(), ['id_street => 'id_street]);
}
а ее присоединение вот такое?
Код: Выделить всё
$param = $salefilter_id;
$query->joinWith([
'controls' => function ($query) use ($param) {
$query->onCondition(['controls.id_salefilter' => $param]);
}
]);
andku83
Сообщения: 988 Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков
Сообщение
andku83 » 2018.03.13, 00:59
ну если у вас в обоих моделях (Sale и SaleFiltersOnControl ) есть поля id_street и вы правильно расставите кавычки
то ДА
З.Ы. но гарантировать то я не могу, я ж не знаю где вы еще ставите кавычки неправильно или еще допускаете какие-то ошибки
an.viktory@gmail.com
Сообщения: 536 Зарегистрирован: 2016.09.05, 23:21
Сообщение
an.viktory@gmail.com » 2018.03.13, 10:21
с кавычками просто в приложении использую другие имена столбцов и там все косяки подсвечиваются IDE а тут нет поэтому в час ночи просто не замечаю уже тонкостей.
только вот еще один косяк когда меняю $query на $this т.е. запихиваю в собственный метод
Код: Выделить всё
$param = $salefilter_id;
$this->joinWith([
'controls' => function ($this) use ($param) {
$query->onCondition(['controls.id_salefilter' => $param]);
}
]);
то пишет cannot use $this as parametr (подсвечивает function
($this) use)
тогда как правильно написать можно ?
andku83
Сообщения: 988 Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков
Сообщение
andku83 » 2018.03.13, 12:16
там где вы написали $this это внутреннее имя переменной в функции, а $this внутри функции (если не ошибаюсь) - это сама функция
andku83
Сообщения: 988 Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков
Сообщение
andku83 » 2018.03.13, 17:14
а так разве не работает?
an.viktory@gmail.com писал(а): ↑ 2018.03.13, 00:54
т.е. связь вот такая
Код: Выделить всё
public function getControls()
{
return $this->hasOne(SaleFiltersOnControl::className(), ['id_street' => 'id_street']);
}
а ее присоединение вот такое?
Код: Выделить всё
$param = $salefilter_id;
$query->joinWith([
'controls' => function ($query) use ($param) {
$query->onCondition(['controls.id_salefilter' => $param]);
}
]);
andku83
Сообщения: 988 Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков
Сообщение
andku83 » 2018.03.14, 12:05
не знаю что вы пытаетесь этим сказать, единственное что можно было бы сделать красивее и чтобы работала автоподстановка:
Код: Выделить всё
$query->joinWith([
'controls' => function (SaleFiltersOnControl $query) use ($param) {
$query->onCondition(['controls.id_salefilter' => $param]);
}
]);
an.viktory@gmail.com
Сообщения: 536 Зарегистрирован: 2016.09.05, 23:21
Сообщение
an.viktory@gmail.com » 2018.03.14, 21:06
Код: Выделить всё
SELECT `s`.* FROM `sale` `s`
LEFT JOIN `control` `controls` ON
(`s`.`id_similar` = `controls`.`id_similar`) AND (`controls`.`id_salefilter`=177)
(`s`.`price` < 'controls.price')
вообщем рендерится в запросе вот так, и из-за последней записи ничего не выводит, ее удаляю и все ок.
еще добавлю что в связь нежесткая т.е. ее может и не существовать (NULL) как быть ?
andku83
Сообщения: 988 Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков
Сообщение
andku83 » 2018.03.15, 15:27
Код: Выделить всё
SELECT `s`.* FROM `sale` `s`
LEFT JOIN `control` `controls` ON
(`s`.`id_similar` = `controls`.`id_similar`) AND (`controls`.`id_salefilter`=177)
WHERE
(`s`.`price` < 'controls.price') OR ('controls.price' IS NULL)
вы уточняйте все требования сразу, иначе заранее никто не догадается что вы туда еще напихаете
а если нужно через QueryBuilder, то показывайте свой