【发布时间】:2019-01-10 20:13:42
【问题描述】:
我想在 Ecto 模型中有一个独特的字段。该字段应该包含一个我可以轻松生成的随机字符串(例如,请参阅here)。但是,我想避免生成字符串并检查它是否已经存在于数据库中,因为这会使我面临竞争条件。
我想让它重试插入,直到找到唯一的字符串。但是我该怎么做呢?它应该在changeset/2 函数内吗?
defmodule LetsPlan.Event do
use LetsPlan.Web, :model
schema "events" do
field :name, :string
field :from, Ecto.DateTime
field :to, Ecto.DateTime
field :slug, :string
timestamps
end
@required_fields ~w(from to)
@optional_fields ~w(slug)
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
|> unique_constraint(:slug)
end
end
【问题讨论】:
-
是的,在
changeset函数和控制器中设置约束,当其他字段准备好时,生成 slug,将其放入变更集中并尝试保存。然后匹配三种情况 a) 它工作 -> 继续 b) 关于 slug 的 changeset.error -> 递归调用自身以生成 slug 并重试 c) 其他错误 -> 处理或出现在 GUI 中。 -
@tkowal 好的,我明白了,但我有一个问题:如何区分错误?例如,我怎么知道插入失败是因为 slug 还是有其他错误?
-
@tkowal 没关系。看了Ecto的源码,发现错误放在
changeset.error。你说了,但我之前没听懂。
标签: elixir phoenix-framework ecto