繁体   English   中英

凤凰et剂中的变更集是什么

[英]What is a changeset in phoenix elixir

我在理解模型中的changeset遇到问题。 它能做什么? 一个模型中可以有多个变更集吗? 例如,一个用于创建,另一个用于更新。

有人可以用一种简单的方式进行详细说明,从而帮助其他人来凤凰城吗?

文档中

变更集允许在处理模型时过滤,强制转换,验证和定义约束。

Ecto模块的入门文档中有一个使用变更集的示例。 函数change / 2和cast / 4是创建变更集的常用入口点,而其余功能对于操作它们非常有用。

变更集用于创建和修改模型。 从字面上看,变更集是一种存储一组变更 (以及验证规则)的结构。您可以将变更集传递给Ecto Repo,以便在变更有效时将其保留。

当将模型传递给更新时的仓库时,Ecto的当前master分支将删除隐式转换,这意味着使用变更集是更新模型的唯一方法。

从变更日志:

给定Repo.update / 2模型已被弃用,因为它无效且容易出错,因为无法跟踪更改

就每个模型具有多个变更集而言,答案肯定是肯定的。 变更集只是一个功能。 实际上,您甚至不需要在模型中放置变更集功能,但这是放置它们的常见地方。

如果在注册用户时需要比更新用户更多的字段,则可以定义带有不同必填字段的register_changesetcreate_changeset

如果您对Rails有点熟悉,ActiveRecord可在模型中集中数据库访问,查询生成和验证,Ecto可将这些职责划分为单独的模块。

ActiveRecord方法在模型类或实例内执行,而Ecto希望您将模型,查询或变更集传递给其函数。

Ecto使用变更集执行验证,而不是处理模型内部的验证。

Ecto变更集提供了验证和约束,一旦出现问题,最终将变成错误。

它们之间的区别在于,可以在不需要与数据库交互的情况下执行验证,因此,验证总是在尝试在数据库中插入或更新条目之前执行。

但是,只有在数据库中执行操作时才能以安全的方式检查约束。 结果,总是在约束之前检查验证。 万一验证失败,甚至都不会检查约束。

让我们来看一个例子:

defmodule User do
  use Ecto.Schema
  import Ecto.Changeset

  schema "users" do
    field :name
    field :email
    field :age, :integer
  end

  def changeset(user, params \\ :empty) do
    user
    |> cast(params, ~w(name email), ~w(age))
    |> validate_format(:email, ~r/@/)
    |> validate_inclusion(:age, 18..100)
    |> unique_constraint(:email)
  end
end

在上面的changeset/2函数中,我们定义了两个验证(一个用于检查电子邮件格式,另一个用于检查年龄),以及电子邮件字段中的唯一约束。

假设给出了电子邮件,但年龄无效。 变更集将出现以下错误:

changeset = User.changeset(%User{}, %{age: 0, email: "mary@example.com"})
{:error, changeset} = Repo.insert(changeset)
changeset.errors #=> [age: "is invalid"]

在这种情况下,我们没有检查电子邮件字段中的唯一约束,因为数据没有验证。 让我们确定年龄并假设该电子邮件已存在于数据库中:

changeset = User.changeset(%User{}, %{age: 42, email: "mary@example.com"})
{:error, changeset} = Repo.insert(changeset)
changeset.errors #=> [email: "has already been taken"]

验证和约束条件在检查发生时定义了明确的边界。 通过将约束移至数据库,我们还提供了一种安全,正确且无数据争用的方法来检查用户输入。

您可以在此处找到更多详细信息Ecto Change Set

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM