Михаил
Пожалуйста, не надо делать из Symfony Laravel. Нравится последний - так и работайте с ним. Но имейте в виду, что многим он не нравится. Любой более-мене опытные разработчик предпочтёт сырой SQL, т.к. он более понятен, чем билдер, который непонятно что сгенерит. На ревью вы будете проверять что там генерирует билдер? Будете потом при апдейте версии доктрины следить, что миграция не стала другой?
Даже не то что многим он не нравится, а просто когда к уже устоявшимся практикам пытаются добавить кардинально другие - то получится котопёс. Я знаю каково это, когда ларавист и симфонист работают на одном проекте. Где-то в src можно провести чёткую границу на которой работал каждый.
Gleb
Билдер удобнее писать. Сырой скл удобнее читать. В ларе насколько я помню не было автогенерации миграций, поэтому там билдер к месту.
Хз, мне сырой писать удобнее, он +/- одинаковый, с небольшими отличиями. А билдер везде свой, помнить надо намного больше. PS: у нас довольно сложные запросы бывают.
Михаил
Билдер удобнее писать. Сырой скл удобнее читать. В ларе насколько я помню не было автогенерации миграций, поэтому там билдер к месту.
Билдер избыточен. Билдер крутой когда у вас есть логика формирование запроса. Хотя как я понял со временем - если в репозитории вам нужно в рантайме переделывать запрос - это плохой запах.
Yevgeniy
Хз, мне сырой писать удобнее, он +/- одинаковый, с небольшими отличиями. А билдер везде свой, помнить надо намного больше. PS: у нас довольно сложные запросы бывают.
Я слаб в скл, поэтому предвзят. Но когда мне надо было что то засидить в бд, то с хотя бы старался использовать коннекшен и пдошлные штуки. Впрочем, не я один. Однако даже чуваку затянувшему квери билдер в up() миграции и получившему от всех по шапке не приходило в голову править миграции на билженые
Михаил
А есть qb для формирования regexp? 🌚
Юра
Сырой запрос: открываем доку по базе данных, читаем Билдер: открываем доку по билдеру читаем И там и там нужно читать доку но в первом случае ты изучаешь то что можнл применить где угодно, а во втором случае ты учишь ларавель
Юра
Ненавижу все эти абстракции которые нкбприносят никакого реального профита
Юра
Понятия не имею. Я пилю норм DI либу для тацпскрипта чтобы получить удобство и скорость
Юра
Мне пофигу на Лару )
Михаил
а ревью на что?
Да, согласен. Не следовало его нанимать
Михаил
у нас другой опыт
Я понимаю что вы пытаетесь меня подколоть, но не получиться, потому что мы знали что так будет и в конечном итоге сервис пришёл к единому стилю
Dmitriy
хм да не хотел подкалывать )
Михаил
Важно не перетягивание одеяла, важно то, что бы каждому было тепло (не геи)
Dmitriy
ну если кодовая база устоялась, то новому программисту к ней все равно надо будет привыкать, причем не важно какой опыт, ларавель или симфони
Юра
А разве di в js это не против правил js?
Нет. Там есть nest js например
Михаил
Ну в любом случае новому программисту нужно будет привыкать к новой кодовой базе. В симфе почти во всех аспектах нет стандарта. Начиная от богатого набора библиотек, заканчивая организацией архитектурных слоёв.
Михаил
Нет. Там есть nest js например
Просто js это вроде про runtime сборку объектов и про прототипо-ориентированное программирование. Как в таком случае уместить di - не ясно Но в любом случае, кидай ссылку, будем посмотреть. Js давно застоялся, без существенных изменений. Может станешь его мессией
Юра
Объекты в рантайме создаются. Не пойму про что ты
Михаил
Объекты в рантайме создаются. Не пойму про что ты
Классов нет, всё создаётся в рантайме
Юра
Есть классы там
Юра
Просто наследование там чуток по другому работает
Михаил
Да? Не видел
Gleb
Не нужно грести свои предпочтения под "опытные разработчики". Тут сильно субъективно. Опять же билдер может дать абстракцию если писать целиком на нем, в отличии от raw
Миграции зачастую потенциально или определенно опасные операции. Использовать билдер для них - это как делать бэкапы, но не проверять их. Обычно всё норм, пока не случится факап.
Юра
Билдеры круты там где они генерируются. И где у тебя весь билдер статически сгенерирован из схемы и проверяет комплитит сразу в идее. А так да помогает возможно меньше ручной писанины меньше вероятности опечаток, но все равно сырой запрос понятен всем и каждому. У нас например запросы должны проходить ревью в датабейс отделе и им билдер не покажешь
Михаил
Ларавед читая чятик по симфе
Павел
Миграции зачастую потенциально или определенно опасные операции. Использовать билдер для них - это как делать бэкапы, но не проверять их. Обычно всё норм, пока не случится факап.
Ну если про факап, то миграция делается минимум локально на определенной версии софта. Он не может тут работать, а там сломаться.
Юра
Но я думаю с билдера можно же получить сырой запрос, он же в итоге его билдит
Павел
Ну конечно если брать какой то прям невероятный инцидент. То чисто теоретически все возмодно. Как возможно что в addSql добавят подкапотом вендора drop database
Павел
Я не спорю что qb не имеет смысла в миграция, и сам же это написал. Но опытный не опытный...,че кого судить, перепись не вели)
Юра
Вопрос только модно ли это сделать прям в миграции или это нужно копать исходники чтобы понять где он там его строит
Gleb
Вопрос только модно ли это сделать прям в миграции или это нужно копать исходники чтобы понять где он там его строит
А вопрос зачем? сначала строить QB, далее получать raw sql. В данном вопросе то изначальный посыл, что raw sql прочитать в коде проще и оценить. А так у того же Ларавель можно миграции в dry режиме запустить и посмотреть raw sql который пойдет. Но это лишние телодвижения на том же ревью. Если абстракция в миграции того стоит - ок, ваш выбор. php artisan migrate --pretend
Юра
Ну допустим для удобства построения пишешь билдер, а потом сырой запрос отправляешь на апрув куда-то
Dmitriy
А как вы raw собираете если по условиям разные секции нужны? Просто конкатинируете строки?
The Ant
Я бы предпочел билдер вместо этой порнографии, но он упадет по памяти )
Vlad
муравей ты теперь в банке работаешь?
Vlad
Не, мое говно )
странно, что фото экрана скидываешь)
The Ant
Телегу просто на комп не хочу ставить
The Ant
Веб клиент лень запускать
Михаил
странно, что фото экрана скидываешь)
да не похоже. Там sql инъекции на лицо
The Ant
да не похоже. Там sql инъекции на лицо
Нету там инъекций. Ууид валидируется
Михаил
в любом случае любая незабинженая хрень - это вектор
The Ant
С биндами сложно :( я бы сделал, но там массивы большие надо будет в памяти ворочать. Так быстрее
The Ant
У мускла кстати всего 2мегабайта на размер запроса лимит
Dmitriy
Яб не пропустил такой МР )
The Ant
Яб не пропустил такой МР )
А какие альтернативы?
The Ant
Ну вот скопилось у тебя за 2 минуты 30-40тысяч строк на обновление. Шо делать?
The Ant
Строить массивы? Их них потом запросы? Это нормально так ест процессор. + Учитывать ограничение на запрос. У меня там просто по 500записей выгребает. А по идее надо вычислять длину запроса, которая не превышала бы размер опции в бд.
Dmitriy
Ну надо разбираться что у тебя за дич в твоем кейсе происходит, так сразу и не скажешь как лучше
The Ant
Ну надо разбираться что у тебя за дич в твоем кейсе происходит, так сразу и не скажешь как лучше
Статистика с фронта сливается в редис, оттуда по крону раз в 2 минуты в бд. Ничо такого.
The Ant
Вместо редиса можно кликхаус какой. Не суть.
Anton
Вместо редиса можно кликхаус какой. Не суть.
Кликхаус не любит мелкие вставки(
Михаил
Кликхаус не любит мелкие вставки(
человек из яндекса знает)
Anton
человек из яндекса знает)
Оу, я вне контекста, мало ли)
Михаил
Статистика с фронта сливается в редис, оттуда по крону раз в 2 минуты в бд. Ничо такого.
Погоди. Статика это картинки, js, css Зачем её сначала в редис потом в бд?
Михаил
Ой блин, глаза в кучу
Михаил
«… Вай малалец. Помогло. Мы ему яйца только до подбородка дотянули, а глаза уже на место встали»
Роман
а чем код в ларе отличается от симвы так норм писать или есть способ получше? private function processBooking(array $booking, Hotel $hotel): void { // Проверяем, существует ли уже бронирование в базе данных /** @var Booking $existingBooking */ $existingBooking = $this->bookingRepository->findOneBy(['number' => $booking['number']]); if ($existingBooking) { // Обновляем существующее бронирование $existingBooking->setHotel($hotel); $existingBooking->setStatus($booking['status']); $existingBooking->setNumber($booking['number']); $existingBooking->setUpdatedAt(new DateTime()); } else { // Создаем новое бронирование $newBooking = new Booking(); $newBooking->setHotel($hotel); $newBooking->setStatus($booking['status']); $newBooking->setNumber($booking['number']); $this->entityManager->persist($newBooking); // Сохраняем новое бронирование в базе данных } $this->entityManager->flush(); // Обновляем изменения в базе данных }
Роман
вообще норм писать такое где либо кроме репозиториев или все crud операции заносить туда, наверно да, а иначе код раздувается капец, в сервиса должна быть только бизнес логика
Михаил
а чем код в ларе отличается от симвы так норм писать или есть способ получше? private function processBooking(array $booking, Hotel $hotel): void { // Проверяем, существует ли уже бронирование в базе данных /** @var Booking $existingBooking */ $existingBooking = $this->bookingRepository->findOneBy(['number' => $booking['number']]); if ($existingBooking) { // Обновляем существующее бронирование $existingBooking->setHotel($hotel); $existingBooking->setStatus($booking['status']); $existingBooking->setNumber($booking['number']); $existingBooking->setUpdatedAt(new DateTime()); } else { // Создаем новое бронирование $newBooking = new Booking(); $newBooking->setHotel($hotel); $newBooking->setStatus($booking['status']); $newBooking->setNumber($booking['number']); $this->entityManager->persist($newBooking); // Сохраняем новое бронирование в базе данных } $this->entityManager->flush(); // Обновляем изменения в базе данных }
ну можно проще private function processBooking(array $booking, Hotel $hotel): void { $booking = $this->bookingRepository->findOneBy(['number' => $booking['number']]); if ($booking === null) { $booking = new Booking(); $this->entityManager->persist($booking); } $booking->setHotel($hotel); $booking->setStatus($booking['status']); $booking->setNumber($booking['number']); $this->entityManager->flush(); }
Михаил
всякие setUpdatedAt можно через хуки доктрины
Роман
как
Михаил
как
https://www.doctrine-project.org/projects/doctrine-orm/en/3.2/reference/events.html#lifecycle-callbacks
Михаил
- Заменить бы ещё массив на dto - Избавиться от сеттеров и заменить их доменным методом у сущности (названия методов не моя сильная сторона) $booking->changeHotelWithStatus($hotelWithStatusDTO); - И пересмотреть флоу при котором тебе зачем то нужно или находить или создавать сущность
Роман
- Избавиться от сеттеров и заменить их доменным методом у сущности это что значит это же основа доктрины или дата маперов
Роман
да я так и планировал перенести сетеры в репозитории