
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

Sergey
20.08.2017
13:01:16

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

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

dypa
20.08.2017
13:02:51

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 должен вернуть тру/фолс в зависимости от удовлетворения условия. Ну удовлетворяет всем условиям, а дальше мне надо изменить сам запрос и передать его объекту дальше на растерзание. Вот изменение запроса, это уже не спецификация ведь, а как раз таки скоуп.

Sergey
20.08.2017
13:13:06

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

Google

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

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

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

dypa
20.08.2017
13:20:31

Sergey
20.08.2017
13:20:57

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
и ответишь на свой вопрос

Roquie
20.08.2017
13:23:58

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 коммитит в бд?

Sergey
20.08.2017
13:26:35

Антон
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
Даже хз как верно перевести. Сущность становится управляемой энтити менеджером?

Sergey
20.08.2017
13:30:58
проверка прав - это не относится к запросам

Антон
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. Простите за нубские вопросы :)