问题描述
我在数据库中有一个json / map字段,它实际上可以根据表中定义的类型字段保存3种对象
所以结构就是这样
field(:type,:string) => user/player/admin
field(:object,:map) => embedded schema needed here. and it can be any of the three schemas ie user/admin/player
那么这是否有可能使我具有MysqL的灵活性以及对Ecto嵌入的美观/支持。
解决方法
您将不得不根据类型将json对象手动转换为嵌入式模式。这可以通过转换轻松完成。
defmodule EnrichedUser do
defmodule User do
defstruct type: nil,name: ""
def new(record),do: %User{type: record.type}
end
defmodule Player do
defstruct type: nil,do: %Player{type: record.type}
end
defmodule Admin do
defstruct type: nil,name: ""
def new(record),do: %Admin{type: record.type}
end
def transform(record = %MyDatabaseUser{type: type}) do
case type do
:user -> User.new(record)
:player -> Player.new(record)
:admin -> Admin.new(record)
_ -> {:error,:unhandled_type}
end
end
end
# Usage example
User |> Repo.all() |> Enum.map(&EnrichedUser.transform/1)
这具有将应用程序逻辑与数据库模型分离的附加好处。现在,您的应用将传递一个EnricedUser.X结构,该结构将作为服务之间的契约,而不是在您进行数据库更改时更改的Ecto模式。