Как изолировать active record в laravel5? Задался вопросом, как безопасно изолировать модели AR и гонять их по приложению, по сервисам, возвращать из репозиториев и тп. ?
Недавно я понял, как не много налажал с архитектурой приложения. Дело в том, что я распылил модели AR по всему проекту, не смотря на то, что я использовал репозитории (как оказалось не правильно).
К примеру у нас есть простой код:$types = Type::with('fields')->get();
Мы берем некие типы из хранилища. Предположим сейчас это AR, а завтра это REST API или Query Builder, в общем результат будет разный. Тоесть в первом случае AR, по втором массив, в третьем коллекция. Не хорошо.
Я бы хотел это все дело привести к одному формату и:
- не боятся, что кто-то умышленно или случайно сделать $type->save() в любом месте проекта
- возвращать единый тип данных из репозитория
- уйти от логики AR, и передавать в виды и между сервисами просто данные (типа как через DTO)
На выручки приходят коллекции:$type = Type::findOrFail($id);
collect($type);
С одной сущностью это хорошо работает, однако когда есть скажем реляции:$types = Type::with('fields')->get();
collect($types->toArray());
То выходит, что все вложенные реляции это просто массив, тоесть не каждая запись в реляции является коллекций, а что-то такое:Illuminate\Support\Collection Object
(
[items:protected] => Array
(
[0] => Array
(
[id] => 1
[alias] => test1
[name] => Новости
[description] =>
[fields] => Array
(
[0] => Array
(
[id] => 1
[type_id] => 1
[type] => test
[is_required] => 1
[validation] => 1
)
)
)
[1] => Array
(
[id] => 2
[alias] => test2
[name] => Статьи
[description] =>
[fields] => Array
(
[0] => Array
(
[id] => 2
[type_id] => 2
[type] => test
[is_required] => 1
[validation] => 2
)
)
)
[2] => Array
(
[id] => 3
[alias] => test3
[name] => Вакансии
[description] =>
[fields] => Array
(
)
)
)
)
Тоесть записи внутри реляции fields, просто массив, а не вложенная коллекция.
Интересует следующие 2 вопроса:
- Правильно ли будет заморочиться с изоляцией AR используя DOT или коллекции ?
- Нужно писать свой обработчик коллекций, который будет конвертировать модель с реляциями рекурсивно в коллекцию со вложенными коллекциями, или есть другой вариант ?

21 Авг 2019 в 07:02
262 +1
0
Ответы
1

Для изоляции Active Record в Laravel и приведения данных к одному формату можно использовать Data Transfer Objects (DTO) или репозитории.

DTO: Создайте классы DTO для каждой сущности (например, TypeDTO), которые будут содержать только необходимые поля и при необходимости вложенные DTO для связанных моделей. Затем в репозитории запрашивайте данные и преобразуйте их в DTO, которые затем можно передавать дальше по приложению. Это позволит избежать использования методов сохранения и других методов AR в разных частях приложения.

Пример:

$type = Type::findOrFail($id);
$typeDTO = new TypeDTO($type);Репозитории: Используйте репозитории для доступа к данным и выполнения операций, возвращающих данные в нужном формате. Репозиторий должен скрывать детали работы с базой данных и возвращать данные в одном формате, независимо от того, какая технология доступа к данным используется (AR, REST API, Query Builder).

Пример:

$types = $typeRepository->getAllTypesWithFields();

Что касается преобразования вложенных реляций в коллекции, можно написать собственный обработчик коллекций или использовать встроенные методы Laravel для преобразования данных. Например, вы можете использовать метод map() для рекурсивного преобразования коллекции и ее вложенных элементов.

Пример:

$types = Type::with('fields')->get();
$typesDTO = $types->map(function ($type) {
$type['fields'] = collect($type['fields']);
return $type;
});

Однако, возможно более эффективным подходом будет использование DTO или репозиториев для структурирования и изоляции данных в приложении.

20 Апр 2024 в 13:09
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир