当 Struct 或 nil 通过时,belongs_to 上的 Ecto validate_required

Ecto validate_required on belongs_to when Struct or nil passed

对显式传递关联的 Struct 执行验证的正确方法是什么?

def changeset(model, params \ %{}) do
  model
  |> cast(params, [:name])
  |> validate_required([:make, :name])
  |> update_change(:name, &String.downcase/1)
  |> unique_constraint(:name, name: :models_name_make_id_index)
end

我将如何使用它:

changeset(%Model{make: make}, %{....})

make 可以为 nil。我想要正确的错误消息而不是:

** (UndefinedFunctionError) function nil.id/0 is undefined or private

验证主要用于处理用户输入,不确保数据一致性。如果您以编程方式创建数据,验证不是防止程序员错误的正确工具(以防有人忘记添加关联)——数据库约束是。

在处理关联的用户输入时,cast_assoc/3cast_embed/3 等函数接受 required: true 选项以强制关联的存在。

创建一个函数来做正确的事情并添加关联可能是个好主意,而不是将逻辑分散到控制器(或调用变更集函数的其他地方)。