@prophp7

Страница 550 из 1387
Roquie
20.08.2017
12:56:16
тогда как решается подобная задача? тру вэй каконийть есть?

Sergey
20.08.2017
12:57:14
тогда как решается подобная задача? тру вэй каконийть есть?
спецификации, явно прописать запросы... я не очень понимаю твою проблему если честно

но скоупы, особенно "дефолтные скоупы" в AR это признанный антипаттерн.

dypa
20.08.2017
12:59:04
и только для подобного
в документации не вижу описания подобных ограничений

Google
Roquie
20.08.2017
13:00:55
спецификации, явно прописать запросы... я не очень понимаю твою проблему если честно
Есть запросы из таблиц, аля достать все записи. У каждой записи прописан user_id. Надо для определенных пользователей вытаскивать только их записи. Таких таблиц много, тут либо для каждого репозитория применять класс-критерий, либо делать его глобальным для всех.

Roquie
20.08.2017
13:02:38
Во первых, не понимаю, где эта логика должна существовать и как решать решать вторую проблему, которая вытекает из казалось бы решенной первой. Как ограничить остальные запросы на апдейт и удаление, чтобы ограниченные юзеры, не смогли подставить айдишник и обновить/удалить не их запись.

Sergey
20.08.2017
13:02:47
это не логика

Roquie
20.08.2017
13:03:19
это не логика
а что это?

Sergey
20.08.2017
13:03:29
почему?! это же документированные возможности инструмента
потому что эффект производимый фильтрами слишком глобальный и его слишком тяжело контролировать

доктрина имеет много очень опасных фич

часть к 3-ей версии наконец удалят

dypa
20.08.2017
13:06:48
вилка и нож тоже опасные - но лично я не собираюсь отказываться от них в повседневной жизни просто потому, что кто то когда то может ими убить самого себя

Sergey
20.08.2017
13:08:57
короч задача решается тупо на уровне репозитория для каждой из твоих сущностей

просто добавляешь условие руками, явно

Google
Sergey
20.08.2017
13:08:57
делается это за 5 минут

предсказуемо

и в случае изменения требований все будет так же предсказуемо

потому не надо тебе от них отказываться)

короч дело твое

я выразил свое мнение

явное лучше неявного, и я не стал бы использовать для логики приложения (особенно на начальных этапах) фичи которые машнят что-то в hint-ах query

Roquie
20.08.2017
13:11:41
шаблон "спецификация" погугли
Не понимаю, как он поможет, если isSatisfiedBy должен вернуть тру/фолс в зависимости от удовлетворения условия. Ну удовлетворяет всем условиям, а дальше мне надо изменить сам запрос и передать его объекту дальше на растерзание. Вот изменение запроса, это уже не спецификация ведь, а как раз таки скоуп.

просто добавляешь условие руками, явно
дык тогда я так добавлю 5 условий для 5 таблиц, чет не красиво, либо куда-то выносить, аля трейт (тоже криво)

Sergey
20.08.2017
13:13:06
дык тогда я так добавлю 5 условий для 5 таблиц, чет не красиво, либо куда-то выносить, аля трейт (тоже криво)
преждевременное обобщение логики и преджевременная оптимизация (не только с точки зрения производительности) - не хорошо

Roquie
20.08.2017
13:13:29
поверь, это уже не преждевременно :) это уже рефакторинг

Sergey
20.08.2017
13:13:36
не поверю)

Антон
20.08.2017
13:13:42
Что то везде про это паттерн спецификация? Это какая то мода?

Sergey
20.08.2017
13:13:52
это очень удобно в контексте доктрины просто

Антон
20.08.2017
13:14:13
Если я просто буду делать запросы в доктрине, это плохо?

Sergey
20.08.2017
13:14:18
тут у тебя два варианта - либо у тебя дублирование не дублирование потому что это разные штуки и могут быть разные правила, либо тебе надо подумать "а не являются ли все эти 5 таблиц одним и тем же"?

Если я просто буду делать запросы в доктрине, это плохо?
нет, не плохо. Просто если у тебя есть много условий и ты хочешь делать новые за счет композиции предыдущих - спецификация тебе это позволяет.

dypa
20.08.2017
13:16:21
короч задача решается тупо на уровне репозитория для каждой из твоих сущностей
в случае если не используются методы вида findBy* - тогда, делается кастомный queryBuilder с доп условием. но тогда есть шанс перейти границу когда ты уже не используешь преимущества doctrine и писать просто sql становится проще

Google
Sergey
20.08.2017
13:16:53
преимущества доктрины в операциях на чтения только если тебе надо на коленке накидать чего, и тут профит только от ленивой загрузки

мощь же доктрины проявляется только в операциях записи

Антон
20.08.2017
13:19:51
Ещё вопрос. Так и не осознал. Должен ли уметь репозиторий сохранять или нет?

Или отдельный класс должен?

Sergey
20.08.2017
13:20:30
почитай про unit of work

Sergey
20.08.2017
13:20:57
Ещё вопрос. Так и не осознал. Должен ли уметь репозиторий сохранять или нет?
если коротко, если ты достал сущность через доктрину и она попала в unit of work то при flush она сохранится сама по себе.

Roquie
20.08.2017
13:22:17
не поверю)
пока я вижу только один выход - прикрутить к Criteria еще и скоупинг, только не для селект запросов, но и для всех остальных. Итого выйдет нечто подобное: $this->postRepository->pushScope(new ForUserOnlyScope()); $this->postRepository->remove($id); // DELETE FROM posts WHERE user_id = 1 AND id = 1 Ну а чтобы админ мог удалять все, будет нечто подобное: if (! $user->inRole('admin')) { $this->postRepository->pushScope(new ForUserOnlyScope()); } $this->postRepository->remove($id); // DELETE FROM posts WHERE id = 1 На мой взгляд так куда прозрачнее, нежели это городить внутри репозитория.

Антон
20.08.2017
13:23:09
@fes0r а если с реквеста данные идут? То persist и flush прямо в контроллере фигачить?

Sergey
20.08.2017
13:23:35
и ответишь на свой вопрос

Sergey
20.08.2017
13:24:16
Roquie
20.08.2017
13:24:52
ну возьми к примеру посты и задачи, 2 таблицы у которых есть user_id

Sergey
20.08.2017
13:25:07
ну

2 репозитория

в каждом добавляются условия

Google
Sergey
20.08.2017
13:25:45
это совершенно разные сущности которые могут даже к разным контекстам принадлежать

а ты пытаешься как-то "убрать дублирование" которого на самом деле нет

Roquie
20.08.2017
13:25:58
> в каждом добавляются условия типа того if (! $user->inRole('admin')) ... ? я на всякий уточняю, мне кажется это дикость, ведь 3-15 строчек будут повторяется везде )

Sergey
20.08.2017
13:26:26
проверку прав запихни в воутеры

Антон
20.08.2017
13:26:26
@fes0r persist делает подготовку данных, а flush коммитит в бд?

Антон
20.08.2017
13:27:07
Есть что на русском почитать на эту тему?

Roquie
20.08.2017
13:28:14
Антон
20.08.2017
13:29:59
An entity can be made persistent by passing it to the EntityManager#persist($entity) method. By applying the persist operation on some entity, that entity becomes MANAGED, which means that its persistence is from now on managed by an EntityManager. 

Sergey
20.08.2017
13:30:45
роутеры?
забыл что мы не про симфони, там воутеры есть

Admin
ERROR: S client not available

Антон
20.08.2017
13:30:56
Даже хз как верно перевести. Сущность становится управляемой энтити менеджером?

Антон
20.08.2017
13:32:18
Видимо это означает что там транзакция стартует куда и попадет эта операция

Sergey
20.08.2017
13:32:24
почитай теперь про flush

если очень упрощенно: - все сущности лежат в unit of work (UoW) - UoW знает какое состояние было у сущностей в момент когда оно впервые о них узнало - когда ты делаешь persist для новой сущности, у тебя сущность добавляется в общую кучу. Но так как для этой сущности ничего ранее небыло то мы просто записываем ее в очередь на вставку. - когда ты делаешь persist для сущности которая уже у тебя была и ты достал ее через UoW - оно смотри что "а так у меня она уже есть" и больше ничего не делает. - когда ты делаешь flush то доктрина берет и делает diff всего состояния которое оно хранить и на основе этого формирует пачку sql запросов

идея в том что бы ты работал с базой как если бы у тебя был просто InMemoryRepository

Google
Sergey
20.08.2017
13:35:44
типа достал объект по ссылке и ничего явно сохранять не надо

Roquie
20.08.2017
13:39:09
а как эти строчки относятся к запросу?
хмммм, ты немного отрезвил меня. Немного отойдем в сторону от удаления и апдейта. Что если забить на Criteria и сделать вот так в контроллере: if ($user->inRole('admin')) { $posts = $this->postRepository->all(); } elseif ($user->inRole('publisher')) { $posts = $this->postRepository->findPostByPublisherId($publisherId); }

Не вдавайся в смысл, здесь интересен другой подход. Вместо глобальной критерии-класса, сделать отдельный метод в репе и затем вызвать его, если роль подходит.

Sergey
20.08.2017
13:40:13
да, как-то так

Roquie
20.08.2017
13:40:21
Вроде как даже прозрачнее.

Sergey
20.08.2017
13:41:14
ну в этим и идея, оно просто и прозрачно. Да, примитично и не слишком интересно

но зато с таким подходом очень сложно проиграть

Roquie
20.08.2017
13:41:57
Да-да, я это и хотел. Черт побери, как же иногда бывает глаз замылен! Спасибо :)

Sergey
20.08.2017
13:42:16
а вот если у тебя это потом разрастется - тогда можно подумать об устранении дублирования - как раз будет больше информации о том откуда это дублирование взялось

Roquie
20.08.2017
13:42:16
И похер, что иф будет в 3-5 местах.

ага

Антон
20.08.2017
13:46:15
Sergey получается что при условии что энтити описано правильно мне не стоит особо парится о том как работает операция вставки. Доктрина сама знает как правильно вставить

Sergey
20.08.2017
13:47:35
пару месяцев назад был баг что мол делаешь у коллекции clear, делаешь 2 раза flush и оно отчищается два раза

но это редкие кейсы

Антон
20.08.2017
13:48:17
Что означает слово консистентность?

Sergey
20.08.2017
13:48:18
со вставкой просто сущностей все хорошо

https://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D0%B3%D0%BB%D0%B0%D1%81%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85

читай википедию

видишь непонятное слово - идешь туда)

Антон
20.08.2017
13:50:00
Понял. Спс

В общем вся сила доктрины как раз в UoW как я понимаю теперь

Двигаюсь от bitrix->laravel->symfony. Простите за нубские вопросы :)

Страница 550 из 1387