Получение актуальных данных модели - PullRequest
0 голосов
/ 17 октября 2019

Предположим, у меня уже есть какая-то модель, и через некоторое время я изменю поле этой модели в другой функции.

Есть ли какой-нибудь хороший способ получить фактические данные (состояние) модели изБД без использования стандартного 'MyRepo.get(MyModel, model.id)'?

case MyModel.create(attr) do
  {:ok, model} ->
    ...some code...
    # here model will update
    Task.start(fn -> Model.do_some(model) end)
    # here I need model with actual data from DB
    {:reply, {:ok, ModelView.render("show.json", model: model)}, socket}
  {:error, message} ->
    ...some code...
end

Ps модель может иметь некоторую предварительно загруженную ассоциацию

1 Ответ

2 голосов
/ 17 октября 2019

Вместо перезагрузки вашей модели вы должны использовать результат Model.do_some(model), который должен вернуть обновленную модель.

Поскольку даже если вы перезагрузите свою модель после Task.start, вы не можете быть уверены,что Model.do_some(model) уже выполнено, поскольку оно было запущено в новой задаче асинхронно.

Так что вы либо делаете это в том же процессе, что и вызывающая сторона:

case MyModel.create(attr) do
  {:ok, model} ->
    model = Model.do_some(model)
    {:reply, {:ok, ModelView.render("show.json", model: model)}, socket}
  {:error, message} ->
end

, либо в новой задаче(Но я не уверен, какая выгода будет)

case MyModel.create(attr) do
  {:ok, model} ->
    task = Task.start(fn -> Model.do_some(model) end)
    case Task.yield(task) || Task.shutdown(task) do
      {:ok, model} ->
        {:reply, {:ok, ModelView.render("show.json", model: model)}, socket}
      _ -> # Timeout reached
    end  
  {:error, message} ->
end

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

def refresh(%module{id: id}) do
  get(module, id)
end

Вам все равно придется предварительно загружать ассоциации вручную.

...