Laravel Сложные запросы и куда их вставлять

z3r9

Новичок
Подскажите пожалуйста как:
1) Делать сложные запросы типа:
SELECT *,
(SELECT test2.value FROM test2 where test1.id = test2.test1_id order by test2.created_at DESC limit 1) as value
FROM test1;
2) где хранить запросы, которые могут повторяться? В документации в контроллерах, по-моему это глупо.
 

fixxxer

К.О.
Партнер клуба
Делать сложные запросы
Хочешь - квери-билдером, хочешь - $pdo = $db->getPdo() и понеслась.

где хранить запросы, которые могут повторяться
Что значит, где хранить? Там, где они выполняются, там и хранить. В коде соответствующего класса.

Хоть повторяющийся, хоть неповторяющийся запрос может быть в контроллере только если ты родом из Индии.

куда их вставлять
Гусары, молчать!
 

z3r9

Новичок
Хочешь - квери-билдером
Просто в примерах нет. В Zend, например, один запрос можно вставлять в другой.

Что значит, где хранить? Там, где они выполняются, там и хранить. В коде соответствующего класса.
Ну так вот я и спрашиваю, а с контроллерами и так понятно. В модели их можно хранить, или для этого есть специальное место?
 

fixxxer

К.О.
Партнер клуба
В модели в смысле активрекорде? Если это фильтр для активрекорд-коллекции - то есть в итоге тебе надо получить eloquent-сущности - для этого есть скоупы. А если нет, то глупость какая-то, какое этот код туда имеет отношение? MVC не означает, что кроме моделей, вьюх и контроллеров ничего нет ;) Могут быть просто классы. Часто такое называют services, мне это не нравится, но грузить тебя не буду - пока и так сойдет, потом сам дойдешь до более вменяемых подходов, да и тут на форуме можно найти обсуждения, если интересно.

В документации почти все есть
https://laravel.com/docs/5.4/queries

Помимо того - можно комбинировать несколько билдеров для тех же подзапросов, гугли в районе laravel query builder getQuery mergeBindings.
 
Последнее редактирование:
  • Like
Реакции: z3r9

Alexey Mezenin

Новичок
1) Делать сложные запросы типа:
SELECT *,
(SELECT test2.value FROM test2 where test1.id = test2.test1_id order by test2.created_at DESC limit 1) as value
FROM test1;
Используй ORM и отношения (Eloquent), если хочешь писать поддерживаемый код.

2) где хранить запросы, которые могут повторяться? В документации в контроллерах, по-моему это глупо.
Все запросы хранишь в моделях. Методы вызываешь из контроллера используя инжектированные модели (читай DI и Container в доках) или с помощью фасадов.
 
  • Like
Реакции: z3r9

fixxxer

К.О.
Партнер клуба
@Alexey Mezenin, насколько я понимаю, у него речь не о моделях, а о запросах типа статистики, результаты которых не маппятся на Eloquent-модели. Ну может я и не прав.

Если мапятся - тогда, конечно, scopes.

Отдельный случай - это когда вроде мапится, но добавляется этакое "виртуальное" read only поле. Тут в рамках AR вообще нормального решения нет, нормально такие вещи получаются только с разделением на read и write models. В рамках AR я такие "виртуальные" поля, да, вынужденно присовываю прямо в Eloquent-модель, но это жуткий костыль, конечно.
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
используя инжектированные модели (читай DI и Container в доках)
Эм, а чего там инжектить-то?

Вот есть у меня SomeEloquentModel::findByFoo($foo). Как это заинжектишь?

Заинжектить можно репозитории, и, да, я так и предпочитаю делать, и вызывать AR-методы, работающие с базой, только из репозиториев, но это совсем не классический laravel-way.
 

z3r9

Новичок
fixxxer, вот и я искал но так и не нашел как выполнить подобный запрос. И что касается репозиториев, в документации об этом не слова.
А и еще, что скажите на счет форм laravelcollective/html. Для работы с формами ничего нет. Стоит их использовать или нет?
 

fixxxer

К.О.
Партнер клуба
Репозитории - это архитектурная концепция, от фреймворка никак не зависит, конечно, в документации Laravel этого нет, так же как в ней нет информации про design patterns, скажем.

А объясни конкретную задачу, зачем тебе такой запрос, к какой модели он относится (или к нескольким, или вообще не относится).

Потому что ответ зависит от.

Насчет форм - я не знаю. Если ты делаешь всякие админки, ну может быть. Я такие вещи предпочитаю делать на JS, на Angular, например, а с сервером работать через REST API или JSON-RPC.
 

z3r9

Новичок
Ну это как вывести в Таблице Сотрудники, последнюю зарплату сотрудника. Относится к таблице Сотрудники. Через Eloquent выводит полностью весь массив зарплат.
 

fixxxer

К.О.
Партнер клуба
Я не спрашиваю, к какой таблице относится, я спрашиваю, к какой модели? Или ни к какой, просто read only объект или массив оных?

Что на выходе надо получить?
 

z3r9

Новичок
Модель Сотрудники связана один-ко-многим с Моделью Зарплаты. В контроллере Сотрудники, нужно вывести список сотрудников и их последнюю зарплату. Это единичный запрос для чтения.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@z3r9, не бывает никакой модели "Зарплаты". Ставка оклада - это поле сущности "Сотрудник". Есть выплаты сотрудникам, и последняя выплата не скажет ничего.
Если это пример - он глупый.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Отдельный случай - это когда вроде мапится, но добавляется этакое "виртуальное" read only поле. Тут в рамках AR вообще нормального решения нет, нормально такие вещи получаются только с разделением на read и write models. В рамках AR я такие "виртуальные" поля, да, вынужденно присовываю прямо в Eloquent-модель, но это жуткий костыль, конечно.
Кто ж тебе мешает разделить на read и write и построить виртуальный AR поверх них? :)
 

Вурдалак

Продвинутый новичок
Кто ж тебе мешает разделить на read и write и построить виртуальный AR поверх них? :)
Зачем это называть «виртуальный AR»? Там что, тоже будет метод $myReadOnlyVirtualAr->save(), но «виртуальный»? Просто объект с данными для чтения.
 

z3r9

Новичок
PHP:
Employee::with('salaries', function($query) {
    $query->orderBy('created_at', 'desc')->take(1);
});
А как вывести конкретное поле? Оно выводит весь массив. В интернете примеры с
Код:
$query->select('поле');
Но с select выводит просто []. Пробовал так же в Модель, в методе "salaries" через select, то же самое.
 

Вурдалак

Продвинутый новичок
Да не нужно использовать AR для этого, напиши отдельный класс который тупо сделает SELECT-запрос в базу.
 
Сверху