我能够通过稍微改变我的数据结构来解决这个问题。自定义字段现在是一个 JSONB 数组,它允许我做一个非常优雅的 embeds_many 关系。实际上,我还没有仔细阅读链接(http://blog.plataformatec.com.br/2015/08/working-with-ecto-associations-and-embeds/)上的文档,之后我意识到我的数据结构不够完善。
因此,与其有一个看起来像的 JSONB 列
{
"name":"Something",
"address":"123 Fake St"
}
看起来像
[
{
"field":"name",
"value":"Something"
},
{
"field":"address",
"value":"123 Fake St"
},
]
这似乎是我用例的最佳选择,但它确实占用了更多空间(因为 Ecto 在幕后为每个对象添加了必需的 ID 字段以确保完整性)。
更改为这种结构后,我只是创建了一个模型并根据链接将它们关联起来。简而言之,它看起来像这样:
defmodule UserManager.CustomField do
use Ecto.Model
embedded_schema do
field :field
field :value
end
@required_fields ~w(field value)
@optional_fields ~w()
@doc """
Creates a changeset based on the `model` and `params`.
If no params are provided, an invalid changeset is returned
with no validation performed.
"""
def changeset(model, params \\ :empty) do
model |> cast(params, @required_fields, @optional_fields)
end
end
defmodule UserManager.Client do
# ...
schema "clients" do
# ...
embeds_many :custom_fields, UserManager.CustomField
# ...
end
# ...
end