Как передать expand в ActiveDataProvider?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Zvook
Сообщения: 21
Зарегистрирован: 2013.03.06, 13:06

Как передать expand в ActiveDataProvider?

Сообщение Zvook »

Всем привет.
При получении данных через ActiveDataProvider возникла потребность получать related модели для последующей сериализации в json,
отсюда вопрос - как передать входной параметр expand в ActiveDataProvider, чтобы он при сериализации подтянул related данные?

PS. В fields объявлять не хочу, так как далеко не везде нужно такое поведение, поэтому объявил в extraFields и нужно теперь данные получить

Nex-Otaku
Сообщения: 831
Зарегистрирован: 2016.07.09, 21:07

Re: Как передать expand в ActiveDataProvider?

Сообщение Nex-Otaku »

В запросе, где у вас "->with" либо "->joinWith", укажите параметр принудительной загрузки "eagerLoading".

Zvook
Сообщения: 21
Зарегистрирован: 2013.03.06, 13:06

Re: Как передать expand в ActiveDataProvider?

Сообщение Zvook »

Nex-Otaku писал(а):
2017.11.26, 11:00
В запросе, где у вас "->with" либо "->joinWith", укажите параметр принудительной загрузки "eagerLoading".
Если бы все было так просто... :)
К сожалению, даже имея подгруженную related модель, сериализатор, ее не забирает. Жадная загрузка включена, все связи выгребаются сразу, но при сериализации в json в итоговом результате их нет. Для этого существует метод fileds() в модели, да, и если там указать явно, что нужно тот или иной релейшен забирать - то все работает. Но мне хотелось бы это реализовать через extraFields(), так как далеко не везде нужно такое поведение. А extraFields() в свою очередь срабатывает только при наличии параметра в запросе expand, с указанием проперти (релейшена), которую нужно подгрузить. Но как передать ActiveDataProvider'у этот expand - не понятно.

Zvook
Сообщения: 21
Зарегистрирован: 2013.03.06, 13:06

Re: Как передать expand в ActiveDataProvider?

Сообщение Zvook »

Т.е. если непосредственно перед созданием дата-провайдера вручную сделать вот так:

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

Yii::$app->request->setQueryParams(['expand' => 'myRelation']);
То все работает. Но это как-то крайне костыльно и хотелось бы передать этот expand в дата-провайдер

Аватара пользователя
SiZE
Сообщения: 2699
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Как передать expand в ActiveDataProvider?

Сообщение SiZE »

expand не надо передавать в DataProvider, он ему без надобности.

Этим занимается сериалайзер.
в поиске работы

Zvook
Сообщения: 21
Зарегистрирован: 2013.03.06, 13:06

Re: Как передать expand в ActiveDataProvider?

Сообщение Zvook »

SiZE писал(а):
2017.11.27, 09:14
expand не надо передавать в DataProvider, он ему без надобности.

Этим занимается сериалайзер.
Ах вот оно что. Поэтому я и не мог в исходниках датаПровайдера найти экспанд этот, не там искал оказывается :)
Ну и судя по коду сериалайзера вижу, что никак не передать ему экспанд напрямую - только через Request.
Что ж, на этом вопрос исчерпан,
Спасибо!

zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: Как передать expand в ActiveDataProvider?

Сообщение zelenin »

Zvook писал(а):
2017.11.27, 11:19
SiZE писал(а):
2017.11.27, 09:14
expand не надо передавать в DataProvider, он ему без надобности.

Этим занимается сериалайзер.
Ах вот оно что. Поэтому я и не мог в исходниках датаПровайдера найти экспанд этот, не там искал оказывается :)
Ну и судя по коду сериалайзера вижу, что никак не передать ему экспанд напрямую - только через Request.
только request может быть вашим кастомным. Впрочем как и сериалайзер.

Аватара пользователя
SiZE
Сообщения: 2699
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Как передать expand в ActiveDataProvider?

Сообщение SiZE »

zelenin писал(а):
2017.11.27, 11:25
только request может быть вашим кастомным. Впрочем как и сериалайзер.
Как можно кастомизировать сериалайзер, чтобы передать ему поля для expand не трогая реквест? Мы находимся в экшене:

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

public function aAction()
{
    $dataProvider = new ActiveDataProvider();
    
    return $dataProvider;
}
Это инициализация сериалайзера

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

/**
  * Serializes the specified data.
  * The default implementation will create a serializer based on the configuration given by [[serializer]].
  * It then uses the serializer to serialize the given data.
  * @param mixed $data the data to be serialized
  * @return mixed the serialized data.
  */
protected function serializeData($data)
{
    return Yii::createObject($this->serializer)->serialize($data);
}
    
/**
  * @inheritdoc
  */
public function afterAction($action, $result)
{
   $result = parent::afterAction($action, $result);
   return $this->serializeData($result);
}
в поиске работы

Аватара пользователя
ElisDN
Сообщения: 5536
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Как передать expand в ActiveDataProvider?

Сообщение ElisDN »

Костылём с переопределением метода getRequestedFields.

Аватара пользователя
SiZE
Сообщения: 2699
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Как передать expand в ActiveDataProvider?

Сообщение SiZE »

ElisDN писал(а):
2017.11.28, 13:24
Костылём с переопределением метода getRequestedFields.
Я думал может какой-то способ годный есть :)
в поиске работы

Аватара пользователя
SiZE
Сообщения: 2699
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: Как передать expand в ActiveDataProvider?

Сообщение SiZE »

ElisDN писал(а):
2017.11.28, 13:24
Костылём с переопределением метода getRequestedFields.
Получается все равно проще кастомизировать реквест для управления expand.
в поиске работы

Аватара пользователя
ElisDN
Сообщения: 5536
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Как передать expand в ActiveDataProvider?

Сообщение ElisDN »

SiZE писал(а):
2017.11.28, 15:43
Я думал может какой-то способ годный есть :)
Годный способ был бы, если б сериалайзер был слабосвязанным:

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

public function serialize($data, $onlyHeaders, $fields, $expand): SerializeResult

Ответить