这似乎是一个非常容易解决的问题,但显然我无法直接思考或看正确的地方。
假设我有一个模式,其中列按照惯例命名为snake_case,例如branch_id
。
通常,如果数据来自Phoenix表单,那么您的数据键与模式的键完全对应,这样您就可以编写%MyStruct{} |> cast(attrs, [:branch_id])
等。
但是,在我的JSON API中,传入的JSON对象将具有camelCase中的键,例如"branchId"
。
是否有来自Ecto.Changeset
的任何函数,我可以使用它来方便地将这些键从传入数据到我的模式中的列?
一个明显的解决方案是(在控制器中)Enum.map
首先传入JSON,使用Macro.underscore
转换键,并将结果收集回地图,然后将其传递给changeset
函数。然而,这似乎是无关紧要和低效的。
这不仅限于snake_case与camelCase的情况,而且可能是密钥看起来与预期列名不同的任何情况。
如果您正在编写将JSON发送到API的客户端,请要求您的API调用JSON密钥为snake_case以匹配API端点。
Macro.camelize
和Macro.underscore
函数也不适用于某些情况,因为它们是do not support unicode or invalid-in-Elixir-identifier characters,因此如果你想接受camelCase并变异为snake_case,你可能想要查看Case2。
您可以有条件地实施重新定义,例如如果您收到带有camelCase密钥,Enum.map
或Enum.filter
的请求并且重新调整,但在大多数情况下,最好只指定您的客户端API调用以匹配您的后端API端点
编辑:将Recase ref更改为Case2,因为Recase显然无法处理unicode:P