基于类型的动态嵌入式架构

问题描述

我在数据库中有一个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模式。