Как изолировать 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 или коллекции ? - Нужно писать свой обработчик коллекций, который будет конвертировать модель с реляциями рекурсивно в коллекцию со вложенными коллекциями, или есть другой вариант ?
Для изоляции 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).
Что касается преобразования вложенных реляций в коллекции, можно написать собственный обработчик коллекций или использовать встроенные методы Laravel для преобразования данных. Например, вы можете использовать метод map() для рекурсивного преобразования коллекции и ее вложенных элементов.
Для изоляции 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 или репозиториев для структурирования и изоляции данных в приложении.