hasOne по двум полям

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

hasOne по двум полям

Сообщение an.viktory@gmail.com »

собственно вопрос, будет ли нормально работать связь при withJOIN если я сделаю так:

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

 public function getOnControls()
    {
        return $this->hasOne(SaleFiltersOnControl::className(), ['salefilter_id' => 'id'])->andWhere(['id_street' => 'id_street']);
    }
    
или мне использовать еще одну связь
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: hasOne по двум полям

Сообщение andku83 »

в большинстве случаев будет работать, andWhere перенесется в внешний WHERE запроса
чтобы не переносился его можно заменить на onCondition([])
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

Re: hasOne по двум полям

Сообщение an.viktory@gmail.com »

желательно чтобы работало во всех случаях)))

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

  $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']);

в данном случае будет работать ?
Последний раз редактировалось an.viktory@gmail.com 2018.03.13, 00:07, всего редактировалось 2 раза.
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: hasOne по двум полям

Сообщение andku83 »

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

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

->andOnCondition(['id_similar' => new \yii\db\Expression('s.id_similar')])
и в Where с price тоже нужно последний аргумент так обернуть
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

Re: hasOne по двум полям

Сообщение an.viktory@gmail.com »

извиняюсь но вообще в начале все не так сделал, предыдущий мой пост переписал
остается только вопрос эстетики: как при объявлении связи передавать переменную (а неглобально как я передал).
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: hasOne по двум полям

Сообщение andku83 »

убрать из связи ограничение и применять его только тогда когда нужно:

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

        $query->joinWith([
            'controls' => function ($query) use ($param) {
                $query->onCondition(['controls.id_salefilter' => $param]);
            }
        ]);
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

Re: hasOne по двум полям

Сообщение an.viktory@gmail.com »

а куда пропало вот это

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

['id_street' => 'id_street']
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: hasOne по двум полям

Сообщение andku83 »

hasOne со всем его содержимым остался в связи, или он тоже должен конфигурироваться?
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

Re: hasOne по двум полям

Сообщение an.viktory@gmail.com »

т.е. связь вот такая

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

 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
Откуда: Харьков

Re: hasOne по двум полям

Сообщение andku83 »

ну если у вас в обоих моделях (Sale и SaleFiltersOnControl) есть поля id_street и вы правильно расставите кавычки
то ДА

З.Ы. но гарантировать то я не могу, я ж не знаю где вы еще ставите кавычки неправильно или еще допускаете какие-то ошибки
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

Re: hasOne по двум полям

Сообщение an.viktory@gmail.com »

с кавычками просто в приложении использую другие имена столбцов и там все косяки подсвечиваются 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
Откуда: Харьков

Re: hasOne по двум полям

Сообщение andku83 »

там где вы написали $this это внутреннее имя переменной в функции, а $this внутри функции (если не ошибаюсь) - это сама функция
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

Re: hasOne по двум полям

Сообщение an.viktory@gmail.com »

и как в результате написать ?
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: hasOne по двум полям

Сообщение andku83 »

an.viktory@gmail.com писал(а): 2018.03.13, 15:53 и как в результате написать ?
а так разве не работает?
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]);
            }
        ]);
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

Re: hasOne по двум полям

Сообщение an.viktory@gmail.com »

я упаковываю $query в ее собственные методы. Желательно написать сразу правильно.
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: hasOne по двум полям

Сообщение andku83 »

не знаю что вы пытаетесь этим сказать, единственное что можно было бы сделать красивее и чтобы работала автоподстановка:

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

$query->joinWith([
            'controls' => function (SaleFiltersOnControl $query) use ($param) {
                $query->onCondition(['controls.id_salefilter' => $param]);
            }
        ]);
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

Re: hasOne по двум полям

Сообщение an.viktory@gmail.com »

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

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) как быть ?
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

Re: hasOne по двум полям

Сообщение an.viktory@gmail.com »

не у кого нет мыслей ?
an.viktory@gmail.com
Сообщения: 536
Зарегистрирован: 2016.09.05, 23:21

Re: hasOne по двум полям

Сообщение an.viktory@gmail.com »

совсем нет ?
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: hasOne по двум полям

Сообщение andku83 »

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

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, то показывайте свой
Ответить