
Alex
27.02.2018
13:53:23

Dmitry
27.02.2018
13:53:41
@nwalker И так тоже.

Alex
27.02.2018
13:53:56
не очень красиво, но сработает

Dmitry
27.02.2018
13:53:56
Или просто сделать два кейса

Google

Dmitry
27.02.2018
13:54:20
Причём каждый - в своей функции
Короче говоря, with - это как unwrap в расте
Лучше бы вместо with сделали какой то аналог Changeset, ну короче говоря просто монаду нормальную
Не уверен что так можно
Но было бы круто

Dmitry
27.02.2018
13:58:04
def request(id) do
case User.get(id) do
{:ok, user} ->
case do_action(user) do
{:ok, true} ->
{:ok, true}
{:error, error} ->
{:error, {user, error}}
end
{:error, error} ->
{:error, error}
end
end
def request(id) do
with {:ok, user} <- User.get(id),
{:ok, true} <- do_action(user) do
{:ok, true}
else
{:error, {user, error}} ->
...
end
end
Мне кажется сделать возвращение ошибки как {:error, error, user} или {:error, {error, user}} намного менее накладно, чем with трансформировать в case портянку.
В особенности, когда этот with состоит из 3 и более элементов.
Тогда это не 2 case-а, а 3+ case-ов вместо одного with-а. Признаюсь честно, я этого точно не смогу понять.

Никита
27.02.2018
14:02:06
у меня with из 10-20 подряд) и ничо. щастлив))

Alex
27.02.2018
14:07:37
У меня вот более интересный кейс с организацией кода. Вот есть модуль, в нем все функции кроме одной сами создают транзакцию. Одна должна вызываться уже в транзакции, потому что там там транзакция такая интересная снаружи.
По всем остальным критериям все функции однородны
И глаз режет, и придумать ничего не выходит

Google

Dmitry
27.02.2018
14:09:09
Я такие вещи обычно с макросами решаю.

Alex
27.02.2018
14:11:02
Проверить не в транзакции ли мы и если нет - инициировать?
Вообще, не хочу сейчас в макросы лезть. Очень давно их не писал, а время поджимает
Пусть так остаётся с комментарием
Приживется эликсир в проекте, тогда уже и макросов добавить можно будет
И часть утилитарного кода на него перенести

Dmitry
27.02.2018
14:37:24
Я думал проблема несколько в другом (в том, что трансакция везде повторяется), здесь тогда нужно смотреть..

Alex
27.02.2018
14:41:33
То, что везде нужна транзакция для меня выглядит довольно естественным. Для тех кейсов, где она нужна, в вызывающем ее открывать не имеет смысла никакого, не его это дело.
> То, что везде нужна транзакция для меня выглядит довольно естественным.
просто сложилась такая ситуация, что на базе завязаны обработчики потоков сообщений, которые хочется запускать в несколько инстансов, но без взаимодействия между ними и с хоть какой-то страховкой от race conditions. поэтому с транзакциями работа идет довольно строго и пишется внимательно.
и в некоторых местах я докатился до advisory locks =(


Анастасия
27.02.2018
15:12:48
Или просто сделать два кейса
есть пара вариантов решения с with
1. самый красивый по-моему
def find(id) do
case Repo.get(Model, id) do
%Model{} = model -> {:ok, model}
nil -> {:error, :model_not_found} — тут можно райзить или номер передать если нужно
end
end
…
with {:ok, model} <- find(id)
2. with %Model{} = model <- Repo.get(Model, id) || {:error, :model_not_found}

Никита
27.02.2018
15:18:24
1 мне больше нравится лично. with чистенький получается. с фолбэк контроллером можно else не делать

Dmitry
27.02.2018
15:23:03
@apelsinka223 Он имел ввиду, что ошибка происходит где-то дальше.
with {:ok, model} <- find(id), {:ok, ...} <- do_something
И если do_something возвращает ошибку, то для какого пользователя.
Из else нельзя получить доступ к model.

Vladimir
27.02.2018
15:23:57
В коде Kazoo третьей версии ЕМНИП был code style, который в частности говорил о запрете на вложенные case. Подобные "лесенки" читаются сложнее, и потому обязательно должны быть распилены и раскиданы по функциям. Но там Erlang.
ИМХО в эликсире вложенные кейсы смотрятся прямо скажем не очень

Анастасия
27.02.2018
15:26:01
мб тогда передавать все что нужно для ошибки, не все же данные будут нужны

Dmitry
27.02.2018
15:27:38
@apelsinka223 Я так и предложил.

Анастасия
27.02.2018
15:28:35
либо обычно есть какое-то изначальные данные, их и отдавать, у меня честно говоря не было случаев когда нужно вычислить и потом передать при ошибке

Google

Dmitry
27.02.2018
15:28:58
Ну вот я и говорю - пилим как в эрланге без with
Теоретически можно отркфакторить мой код с with

Dmitry
27.02.2018
15:29:47
@Virviil Получится меньше кода и читабельнее код и ошибки самодостаточные.
Вероятно.

Артем
27.02.2018
16:06:14
посоны
как книжка? https://www.labirint.ru/books/577008/

Alex
27.02.2018
16:06:45
коли уж на то пошло
http://elixirstatus.com/p/nXym-asyncwith-v030-released-the-asynchronous-version-of-elixirs-with-

Артем
27.02.2018
16:08:08

Alex
27.02.2018
16:08:36

Vladimir
27.02.2018
16:09:22
Или крупные буквы и поля по пять сантиметров.

Артем
27.02.2018
16:09:38
в общем, если кто читал, фидбэк был бы кстати

Alex
27.02.2018
16:10:07
Можно в группе ерлангистов кинуть запрос

Артем
27.02.2018
16:11:07

Alex
27.02.2018
16:11:28

Артем
27.02.2018
16:11:43
спасибо

Vladimir
27.02.2018
18:01:47
Random question: Кто-нибудь на Gigalixir пробовал проекты с сокетами деплоить? Ловлю 403 ошибку, документация на эту тему хромает.
UPD: Вопрос снят.

Nikolay
27.02.2018
18:07:08
могу наврать, но там nginx надо ещё конфигурить
ну или любой другой фронтенд сервер

Google

Vladimir
27.02.2018
18:13:25
gigalixir ближе к heroku в этом плане, не сильно много дают поконфигурировать, хотя консоль есть
Не копал ещё глубоко

Dmitry
27.02.2018
21:13:42
Нашёл эрический косяк в экто:
Если ТРИГГЕРОМ в ИНСЕРТЕ задать какое-нибудь поле, то оно не задаётся в результирующей структуре после Repo.insert
Т.е.
> Repo.insert(%User{})
{:ok, %User{id: 1, name: nil}
> Repo.get_by(User, 1)
%User{id: 1, name: "Вася"}
Если имя задаётся триггером
Я даже не знаю, в какое спортлото писать по этому поводу

Анастасия
27.02.2018
21:28:51
добавь параметр returning: true
в ecto 2.2 добавили параметр, insert возвращает не делая запроса, т.е. только указанные поля в changeset, и id не настоящий

Taras ?
27.02.2018
22:11:18
??

Aleksandr
27.02.2018
22:11:35

Dmitry
27.02.2018
22:15:38
Хрень собачья
Ну хоть починить как то можно

Roman
28.02.2018
04:54:47
Repo.insert не читает после записи же. Можно read_after_write указать, тогда все по идее должно быть норм

Dmitry
28.02.2018
06:07:11
Я никогда на это внимания не обращал, а тут типо все знают
Прост интересно откуда

Fey
28.02.2018
06:39:34
Потому что инсерт в sql не возвращает добавленные данные сам по себе, для этого надо делать отдельный селект. Если бы в экто этот селект принудительно делали неявно, был бы ппц.

Dmitry
28.02.2018
06:48:22
0 логика

Fey
28.02.2018
06:54:04
Очевидно, потому триггеры нечасто используются и структура, которую вернёт селект будет такой же => этот селект будет лишним только оверхедом. А если всё-таки надо, то есть та опция, о которой была речь выше.
вообще конечно, это стоило бы отметить в документашке по insert

Dmitry
28.02.2018
06:58:30
Вообще конечно это есть в доках, но вопрос «зачем возвращают структуру» остаётся открытым

Google

Dmitry
28.02.2018
06:59:12
Потому что в продукте, который позиционирует себя настолько explicit - это просто дыра
Пусть бы они changeset возвращали тогда, в котором было бы доп поле о том, что операция на бд прошла
Если ты выдаёшь объект после инсерта, то он должен быть консистентным

Nikolay
28.02.2018
07:01:22
Это было б “не френдли"

Dmitry
28.02.2018
07:01:48
Самое Френдли - это AR
Где вообще нету чейнджсетов

Nikolay
28.02.2018
07:02:36
йеп, и поэтому такое большое комьюнити)

Dmitry
28.02.2018
07:02:53
Можно было бы сказать, что они делают так под easy controllers
Но жато используется не только в фениксе
Так что ребята проебались как по мне
Ну вернее я проебался, потому что пропустил это в доке, потому что думал что если возвращается объект - то он соответствует бд )

Alex
28.02.2018
07:08:18
так если ты чего-то засунул в changeset кинул это в БД и оттуда пришло все ok, то очевидно, что в БД тоже самое что и в changeset, так почему бы этот changeset не преобразовать в schema для удобства
тем более что это работает, и весьма неплохо

Артем
28.02.2018
07:21:42
0 логика
в мире много удивительного https://github.com/benoitc/hackney/issues/371

Dmitry
28.02.2018
07:23:25
А иначе все превращается в Руби