如何将关联传递到 Ecto 中的变更集?

asi*_*niy 5 elixir ecto phoenix-framework

我有一个非常简单的Comment模型:

  schema "comments" do
    field :content, :string
    belongs_to :user, MyApp.User
    timestamps
  end
Run Code Online (Sandbox Code Playgroud)

我想创建一条新记录,并且希望changeset验证该用户是否存在。我怎样才能做到这一点?

我的 ecto 版本是1.1.8.

Dog*_*ert 5

正确的做法是让数据库处理数据完整性。在您的应用程序中为此编写检查很容易出现竞争条件。User如果在验证和插入之间删除a 会怎样Comment?如果删除User带有任何现有s 的a 会怎样?Comment在数据库中处理此问题将确保数据库中永远不会有无效数据。

首先,确保该user_id字段设置为references(:users)

create table(:comments) do
  ...
  # Check out the various :on_delete options you can pass to here: https://hexdocs.pm/ecto/Ecto.Migration.html#references/2
  add :user_id, references(:users, on_delete: :nilify_all)
end
Run Code Online (Sandbox Code Playgroud)

然后,在您的changeset函数中,在管道到 后cast,添加以下内容:

|> Ecto.Changeset.assoc_constraint(:user)
Run Code Online (Sandbox Code Playgroud)

user_id这会将数据库返回的相关错误转换为正常的变更集错误。您可以Ecto.Changeset.assoc_constraint/3 在此处阅读更多相关信息。另见Ecto.Changeset.html#foreign_key_constraint/3