Модели в фреймворках

AmdY

Пью пиво
Команда форума
Я пивашу с джавистами, использующими Оракл.У них взаимодействие с базой на уровне вызовов процедур-функций, а там пусть ДБА разбираются в своих таблицах и sql. Им не AR, ни ORM не нужны, так как они вообще не владеют информацией о внутреннем устройстве стораджа.

Я в основном работаю в сфере ERP. Потому Eloquent или Doctrine у нас выступает как репозиторий, который выгребет данные и вернёт нам структуру-документ, данные из которого мы потом ручками мэпин на наши модели. Получается двойной мэпинг и в принципе хватало бы DBL + QueryBuilder, но даже у нас более 90% это обычный CRUD и Eloquent-Doctrine помогает в этой рутине.

Надо как-нибудь попробовать Doctrine ODM, но на hello world не прочувствуешь, а на реальных проектах слишком рискованно, проще ходить по знакомым граблям.
 

fixxxer

К.О.
Партнер клуба
Двойной маппинг - это и есть persistence models, которые потом мапятся на domain models. По сути это data mapper вручную. Если не лень это писать, то, в принципе, нормально. Мне лень :)
 

AmdY

Пью пиво
Команда форума
Двойной маппинг - это и есть persistence models, которые потом мапятся на domain models. По сути это data mapper вручную. Если не лень это писать, то, в принципе, нормально. Мне лень :)
а какие варианты, кроме ручного мэпинга? вон в доктрине сколько понаворатили, а по сути там эти самые persistence models с привязкой к одной таблице и одному стораджу. Мне кажется, любая попытка сделать полноценный автомэпинг будет слишком дорогой и не универсальной.
 

Фанат

oncle terrible
Команда форума
Двойной маппинг - это и есть persistence models, которые потом мапятся на domain models. По сути это data mapper вручную. Если не лень это писать, то, в принципе, нормально. Мне лень :)
Кость, ну вот если говорить об автомапиинге.
Я правильно понимаю, что в базовом варианте, в прародительском классе для маппера все равно есть An object that wraps a row in a database table?
Я не хочу пока лезть в дебри с записной книжкой. Пусть у меня будет Товар. У которого, допустим, количество берется из связанной таблицы, а все остальное - тупой деревянный маппинг полей на свойства.
Я, кстати, правильно понимаю, что запись из таблицы товаров может выступать в качестве aggregate root? На который потом навешиваются допольнительные свяязи. Или я все опять неправильно понял?
 

Вурдалак

Продвинутый новичок
Пусть у меня будет Товар. У которого, допустим, количество берется из связанной таблицы, а все остальное - тупой деревянный маппинг полей на свойства.
Что такое «Товар» и его количество? OrderLine или товар (продукт) с оставшимся количеством на складе?
 

Фанат

oncle terrible
Команда форума
Что такое «Товар» и его количество? OrderLine или товар (продукт) с оставшимся количеством на складе?
товар (продукт) с оставшимся количеством на складе
Ну неважно на самом деле. Я из головы пытаюсь выдумать самый простой случай, когда доменная модель не ложится на одну таблицу.
Пример не очень хороший.
У меня пока есть только скидка, но она внешняя совсем по отношению к товару, и не персистится в базу, а получается из сервиса.
 

fixxxer

К.О.
Партнер клуба
Полный автомаппинг недостижим, но в него укладывается большинство случаев. Намного удобнее задавать кастомный маппинг только на те значения, где он требуется.

Если исходить из того, что персистится всегда aggregate root, эта задача заметно упрощается.

И, опять же, это все исключительно про write models. Для read models ORM (по крайней мере в полном смысле слова) вообще не нужен.
 

Вурдалак

Продвинутый новичок
И, опять же, это все исключительно про write models. Для read models ORM (по крайней мере в полном смысле слова) вообще не нужен.
Именно для read models нужны эти таблицы с полями. write-model прекрасно бы обошлась одиним JSON-полем и всё. То есть в этом смысле ORM и реляционные связи нужны именно для того чтобы быстро считывать по разным запросам с индексами. А write-model нужен только PK.
 

Фанат

oncle terrible
Команда форума
Для read models ORM (по крайней мере в полном смысле слова) вообще не нужен.
Объясни.
Почему не нужен?
Вот допустим у нас ид товара (ок, агрегатного корня) - почему мы не можем по нему вытянуть из БД корень и в модели нацепить на него на него сопутствующую инфу?
 

fixxxer

К.О.
Партнер клуба
Именно для read models нужны эти таблицы с полями. write-model прекрасно бы обошлась одиним JSON-полем и всё. То есть в этом смысле ORM и реляционные связи нужны именно для того чтобы быстро считывать по разным запросам с индексами. А write-model нужен только PK.
Я не совсем точно выразился :) ORM нужен, чтобы разложить свойства write-модели по полям в табличках. А вот само это раскладывание нужно, конечно, для того, чтобы можно было писать произвольные SQL-запросы, на основании которых строить read-модели.

Но при этом маппинг на read model односторонний и настолько простой, что это полноценным ORM и не назвать. В простых случаях можно вообще обойтись pdo-шным FETCH_CLASS.
 

fixxxer

К.О.
Партнер клуба
Объясни.
Почему не нужен?
Вот допустим у нас ид товара (ок, агрегатного корня) - почему мы не можем по нему вытянуть из БД корень и в модели нацепить на него на него сопутствующую инфу?
Что значит "нацепить инфу"? :)
 

WMix

герр M:)ller
Партнер клуба
Фанат, в случае если задача вести учет складской единицы, (сложил умножил подитожил) совершенно по барабану какой производитель, группа или название товара у этой единицы. (Или о какой инфе речь?) Интереснее номер, количество, лоток и тд.

Если вопрос показать пользователю состояние, (сгенерить html/json) там вообще orm мешает.
 

WMix

герр M:)ller
Партнер клуба
Ну вот мне нужно показать товар на странице
это очень смешаная информация из нескольких таблиц, там все для людей. Конечно нет ничего плохого иметь конечный метод (query) который вернет этот результирующий набор строк, по определенному фильтру с пагинацией и сортировкой. но все это только для того чтоб передать на view. А на том уровне (twig/js), мало кто оценит иерархию классов (автокомплит не работает, методов нет - голимый struct) , да и все это нужно чтоб нарисовать строчку и кнопочку, которая из всего возьмет только id и при нажатии сгенерит POST. а вот дальше интереснее: нам нужно по id вытянуть обьект изменить его состояние и записать обратно, и в этом случае маппер и хорошо построеный обьект большая помошь
 
Последнее редактирование:

Yoskaldyr

"Спамер"
Партнер клуба
А на том уровне (twig/js)
js - быть может, но тот же твиг прекрасно автокомплитит

Мне кажется @Фанат имел ввиду что в датамеппере уже есть методы для извлечения записей, которые при правильно спроектированной структуры базы в 90% случаев подходят для отображения. особенно когда речь идет об извлечении связанных записей (релейшенов), типа get($id)->with(['relation1', 'relation2']). понятно что когда выборка сложная или сильно хитрая, то нужны будут прямые запросы, но писать запросы для таких примитивных выборок постоянно - напрягает.
 

fixxxer

К.О.
Партнер клуба
В смысле? Ну вот мне нужно показать товар на странице. Что плохого написать $productMapper->load($id);?
Если это та же штука, которой делали save(), то не поможет: геттеров-то нету!

Но на самом деле не поэтому (положим, через reflection достанем, если уж захотелось). Вот открой прямо тут страницу форума со списком тем, там где данные о самом форуме, список тем на странице, число комментариев, дата последнего комментария и прочее. Это ж сколько агрегатов придется вытащить?

И таких вариантов отображения по сути одного и того же форума может быть сколько угодно.

Это не значит, конечно, что никакого маппера вообще не может быть (обычно есть какой-нибудь automapper), но это совсем другой маппер :)
 

Yoskaldyr

"Спамер"
Партнер клуба
@WMix никто не мешает прописать тайпхинт в шаблоне и "магическим" образом появляется автокомплит
 

Фанат

oncle terrible
Команда форума
Эх, ничего не понял, ну ладно.
Буду пилить дальше, чтобы понять
 
Сверху