Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 验证三分之一所需的__Elixir_Phoenix Framework_Ecto - Fatal编程技术网

Elixir 验证三分之一所需的_

Elixir 验证三分之一所需的_,elixir,phoenix-framework,ecto,Elixir,Phoenix Framework,Ecto,我有Xyz,它要么有国家id,要么有联邦州id,要么有城市id。但其中只有一个(不是全部三个,也不是两个)。我如何对此进行验证?另外,我如何才能仅对该字段执行关联约束/1 defmodule Example.Location.Xyz do use Ecto.Schema import Ecto.Changeset alias Example.Location.Xyz schema "xyzs" do field :name, :string belongs_to

我有
Xyz
,它要么有
国家id
,要么有
联邦州id
,要么有
城市id
。但其中只有一个(不是全部三个,也不是两个)。我如何对此进行验证?另外,我如何才能仅对该字段执行
关联约束/1

defmodule Example.Location.Xyz do
  use Ecto.Schema
  import Ecto.Changeset
  alias Example.Location.Xyz

  schema "xyzs" do
    field :name, :string
    belongs_to :country, Example.Location.Country
    belongs_to :federal_state, Example.Location.FederalState
    belongs_to :city, Example.Location.City

    timestamps()
  end

  @doc false
  def changeset(%Xyz{} = xyz, attrs) do
    school
    |> cast(attrs, [:name, :country_id, :federal_state_id, :city_id])
    |> validate_required([:name, :country_id, :federal_state_id, :city_id])
    |> assoc_constraint(:country)
    |> assoc_constraint(:federal_state)
    |> assoc_constraint(:city)
  end
end

我将创建一个函数来检查3个字段中是否有1个字段存在,并添加正确的
assoc\u约束

@doc false
def changeset(%Xyz{} = xyz, attrs) do
  school
  |> cast(attrs, [:name, :country_id, :federal_state_id, :city_id])
  |> validate_required([:name])
  |> validate_one_of_present([:country_id, :federal_state_id, :city_id])
end

def validate_one_of_present(changeset, fields) do
  fields
  |> Enum.filter(fn field ->
    # Checks if a field is "present".
    # The logic is copied from `validate_required` in Ecto.
    case get_field(changeset, field) do
      nil -> false
      binary when is_binary(binary) -> String.trim_leading(binary) == ""
      _ -> true
    end
  end)
  |> case do
    # Exactly one field was present.
    [field] ->
      without_id = field |> Atom.to_string |> String.replace_suffix("_id", "") |> String.to_existing_atom
      assoc_constraint(changeset, without_id)
    # Zero or more than one fields were present.
    _ ->
      add_error(changeset, hd(fields), "expected exactly one of #{inspect(fields)} to be present")
  end
end

代码未经测试,如果发现任何错误,请告诉我

哇,我不知道你能在案件陈述中吹毛求疵。但这绝对有道理。