【问题标题】:Find out if child changeset is being created or updated in elixir phoenix查看是否在 elixir phoenix 中创建或更新子变更集
【发布时间】:2019-12-23 09:19:25
【问题描述】:

我有一个正在创建或更新的嵌套模型。您可以将其视为具有多个 cmets 的帖子,只是在这种情况下,它是具有多个警报的设备。为了显示正确的表单和正确的操作,我在我的父(设备)模板中使用了以下代码:

<%= if @alarm.data.id do %>
        <%= render AppWeb.AlarmView, "form.html", changeset: @alarm, action: Routes.device_alarm_path(@conn, :update,
        @device, @alarm.data.id), message: @last_message %>
 <% else %>
        <%= render AppWeb.AlarmView, "form.html", changeset: @alarm, action: Routes.device_alarm_path(@conn, :create,
        @device), message: @last_message %>
<% end %>

@data 在这两种情况下都是变更集。

@alarm.data.id 的检查似乎不干净。 @alarm.data 永远不会为零,所以我没有收到运行时错误,但仍然......我应该如何处理这个问题?

【问题讨论】:

  • 有一个action 字段docs 保存当前操作(插入/更新)。这有什么帮助吗?
  • 那个动作总是空的。我认为原因是我在更新或创建变更集之前正在查看它。不过谢谢你的想法。
  • 转念一想:你的意思是我应该在控制器中手动设置该操作吗?

标签: elixir phoenix-framework


【解决方案1】:

您可以在模板之外处理此问题,例如在控制器中使用Ecto.Repo.insert_or_update/2 方法。它使用 Ecto.Schema.Metadata:state 字段作为您的变更集,以确定警报 schema 是否已经持续存在。

所以,你的模板就是:

<%= render AppWeb.AlarmView, "form.html", changeset: @alarm, action: Routes.device_alarm_path(@conn, :create_or_update, @device), message: @last_message %>

然后,在您的控制器中,您将拥有此功能:

def create_or_update(conn, %{"alarm" => alarm}) do
  case Repo.insert_or_update(alarm) do
    {:ok, alarm} -> ... 
    {:error, changeset} -> ...
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-17
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多