Страница 1 из 1

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

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

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

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

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

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

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

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

Добавлено: 2017.11.27, 04:12
Zvook
Т.е. если непосредственно перед созданием дата-провайдера вручную сделать вот так:

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

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

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

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

Этим занимается сериалайзер.

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

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

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

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

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

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

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

Добавлено: 2017.11.28, 09:23
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);
}

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

Добавлено: 2017.11.28, 13:24
ElisDN
Костылём с переопределением метода getRequestedFields.

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

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

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

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

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

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

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

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