【问题标题】:control flow for custom validation in phoenix schema凤凰模式中自定义验证的控制流
【发布时间】:2017-11-08 03:47:57
【问题描述】:

我正在尝试在我正在开发的 phoenix 应用程序的架构中实现一些验证。我的架构上有一个属性:details,它包含(除其他外)一个包含(除其他外)有关问题和答案的数据的地图。一个例子:

%{
  question: "What's for dinner?",
  options:[
    %{option: "Chicken", selected: false},
    %{option: "Fish", selected: true}
  ]
}

该模式还有一个 :type 属性,用于描述 :details 映射的内容。我编写了以下验证,以确保 :details 映射在 :type 为“对话”时包含一组选项。

def validate_dialogue_options(changeset) do
  validate_change(changeset, :details, fn :details, details ->
    if(changeset.changes.type == "dialogue") do 
      cond do
        Map.has_key?(details, :options) ->
          []
        true ->
          [details: "must include options for dialogue events"]
      end
    else
      []
    end
  end)
end

这行得通,但感觉真的很麻烦。我对长生不老药相当陌生,所以我确信有一种更简洁的方法可以完成上述操作。任何人都可以推荐一种更简化的方式来实现上述内容吗?

谢谢!

奖励:我目前正在进行额外的验证,以确保在详细信息图中至少选择了一个选项。现在我正在使用下面的方法,但我对更简洁的实现感兴趣!

Enum.member?(Enum.map(details.options, fn(x) -> x.selected end), true)

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

    第一部分可以使用模式匹配来简化。我们对两个词感兴趣,changeset.changes.typedetails,所以我们匹配这些词的元组。

    validate_change changeset, :details, fn :details, details ->
      case {changeset.changes.type, details} do
        {"dialogue", %{options: _}} -> []
        {"dialogue", _} -> [details: "must include options for dialogue events"]
        _ -> []
      end
    end
    

    第二个可以使用Enum.any?/2进行简化

    Enum.any?(details.options, fn x -> x.selected end)
    

    甚至

    Enum.any?(details.options, & &1.selected)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多