【问题标题】:How to toggle update model bool attribute?如何切换更新模型布尔属性?
【发布时间】:2015-11-10 23:12:28
【问题描述】:

如何在更新操作中切换active bool 属性?我习惯了 Rails,Phoenix 有什么好的做法?

示例代码:

defmodule Todo.task do
  use Todo.Web, :model

  schema "task" do
    field :active, :boolean, default: false

    timestamps
  end

  @required_fields ~w(active)
  @optional_fields ~w()

  def changeset(model, params \\ :empty) do
    model
    |> cast(params, @required_fields, @optional_fields)
  end
end

defmodule Todo.TaskController do
  use Todo.Web, :controller
  alias Todo.Task

  def update(conn, %{"id" => id}) do
    task = Repo.get_by(Task, id: id)
    # task.active = !task.active
    # task.save
    render(conn, "show.json", task: task)
  end
end

【问题讨论】:

    标签: elixir phoenix-framework ecto


    【解决方案1】:

    您可以将Ecto.Changeset 与您的新活动状态一起使用,然后调用Repo.update/2

      def update(conn, %{"id" => id}) do
        task = Repo.get_by(Task, id: id)
        changeset = Task.changeset(task,%{active: !task.active})
        case Repo.update(changeset) do
          {:ok, task}         -> redirect(conn, to: task_path(conn, :show, task))
          {:error, changeset} -> render(conn, "edit.html", changeset: changeset)
        end
      end
    

    调用Repo.updateRepo.insert 时的模式匹配被认为是您想要做的最佳实践。

    通常你会使用你在函数中匹配模式的参数调用更新:

      def update(conn, %{"id" => id, "task" => task_params}) do
        changeset = Task.changeset(task, task_params)
        case ...
      end
    

    在您的模型上定义的changeset/2 函数将确保只能修改指定的字段。如果更新时这些与字段不同,请考虑创建update_changeset/2 函数。这个函数没有什么特别之处,你可以定义和使用尽可能多的函数来返回一个变更集。

    【讨论】:

    • 因此,如果我在模型中有很多属性,那么我只能将一个更改传递给变更集,这是关键。我可以创建一个模型方法并从中仅更新 active 标志并处理变更集吗?
    • @luzny 在changeset 函数中调用Ecto.Changeset.cast/4 时指定有效参数(可选和必需)。在这种情况下,您指定 active 是必需的。
    • 您可以将模型传递给Repo.update/2,但我不建议使用它,因为它在 1.1 github.com/elixir-lang/ecto/blob/master/CHANGELOG.md#v110 中已被弃用
    猜你喜欢
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    • 2014-09-12
    • 1970-01-01
    • 1970-01-01
    • 2017-09-27
    • 2012-07-21
    • 1970-01-01
    相关资源
    最近更新 更多