Запретить запрос связанных данных через свойство (with/joinWith)

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

Запретить запрос связанных данных через свойство (with/joinWith)

Сообщение Krown »

Здравствуйте.
Для доступа к связанным данным используются методы модели hasOne/hasMany, которые записывают в свойство объекты связанных данные.
Например:
модель User

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

	...
	public function getStatus()
	{
		return $this->hasOne(Status::class, ['status_id' => 'id']);
	}
И теперь если делать запрос вида $user = User::find()->with('status')->all();, то можно получить поле status, через обращение к $user->status. Однако, даже если не писать with('status'), то само по себе обращение к свойство делает запрос в БД.
В общем меня интересует вопрос, можно ли сделать так, чтобы при обращении к свойству не инициировалcя запрос связанных данных, если он не был описан в модели через with/joinWith.
Т.е. должно быть:

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

	...
	$user = User::find()->all();
	...
	var_dump($user->status); //должно быть null, а не запрос в бд с последующим выводом массива объектов Status, т.к. не было явного указания with('status').
Аватара пользователя
Alexum
Сообщения: 683
Зарегистрирован: 2016.09.26, 10:00

Re: Запретить запрос связанных данных через свойство (with/joinWith)

Сообщение Alexum »

Для чего такие сложности? Если вы получите желаемое, то придётся всегда жёстко контролировать, что вы не забыли сделать "with" там, где в дальнейшем потребуется связь. Не проконтролировали, обратились к связи через свойство - не получили связанную модель, которая в реальности есть в БД. Вы же сами определяете места обращения через связи и должны знать, где заведомо делать жадную загрузку, а где обойтись без неё. Считайте тот же контроль, только с гораздо меньшими рисками.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Запретить запрос связанных данных через свойство (with/joinWith)

Сообщение unknownby »

При твоём $user->status он обращается к твоему методу getStatus, который прописан в модели.

Все ж логично. Ты сделал выборку пользователей. У тебя нет никаких связей сразу в запросе, но если тебе надо получить статус, то через модель, а не первоначальный поиск, ты получишь статус.
Krown
Сообщения: 13
Зарегистрирован: 2018.10.31, 17:57

Re: Запретить запрос связанных данных через свойство (with/joinWith)

Сообщение Krown »

Просто дело в том, что у меня есть некая форма для поиска, в которой есть чекбокс для поиска по названию файлов. Допустим изначальный запрос выглядит как $article = Arcticle::find()->where(['name' => $this->name]). Если чекбокс отмечен, то запрос дополняется конструкцией $article->joinWith('file') и в конце возвращается dataprovider.
А в самом представлении на выводе таблиц со статьями помимо названия еще и делается вывод названия файлов (если чекбокс отмечен), что делается проверкой наличия свойства $article->files, но я не могу проверить простым условием if ($article->files) поскольку он всегда будет true, ибо как сказали выше - будет обращение к методу getFiles.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Запретить запрос связанных данных через свойство (with/joinWith)

Сообщение unknownby »

А если сделать проверку на то, что чекбокс выбран или нет, там где имя файла? Если выбран, тогда выдавать имя файла.
Krown
Сообщения: 13
Зарегистрирован: 2018.10.31, 17:57

Re: Запретить запрос связанных данных через свойство (with/joinWith)

Сообщение Krown »

unknownby писал(а): 2020.02.22, 23:41 А если сделать проверку на то, что чекбокс выбран или нет, там где имя файла? Если выбран, тогда выдавать имя файла.
Ну собственно я и пришел к этому решению, на рендере имени в gridview я проверяю чекбокс из модели формы и если он отмечен, то обращаюсь к свойству файлов, а иначе просто пропускаю его. Просто мне кажется это решение не до конца правильным.
unknownby
Сообщения: 749
Зарегистрирован: 2019.11.05, 16:34
Контактная информация:

Re: Запретить запрос связанных данных через свойство (with/joinWith)

Сообщение unknownby »

Krown писал(а): 2020.02.24, 22:26
unknownby писал(а): 2020.02.22, 23:41 А если сделать проверку на то, что чекбокс выбран или нет, там где имя файла? Если выбран, тогда выдавать имя файла.
Ну собственно я и пришел к этому решению, на рендере имени в gridview я проверяю чекбокс из модели формы и если он отмечен, то обращаюсь к свойству файлов, а иначе просто пропускаю его. Просто мне кажется это решение не до конца правильным.
Почему? Логика в том, что у тебя всегда, например, будет вывод имени файла и его свойств, но выводить его нужно в определённое время, когда где-то что-то выбрано.
Делать такую проверку if(!empty($article->files)) можно, если ты в представлении выводишь без каких либо фильтров инфу с учётом того, что связь есть.
Ответить