【问题标题】:Using ecto to store custom information使用ecto存储自定义信息
【发布时间】:2015-12-19 21:40:35
【问题描述】:

我正在重新实现我最初在 Phoenix 的 Rails 中编写的应用程序,用户可以在其中使用 PostgreSQL 的 JSONB 记录类型创建自定义字段。例如,我们有以下(简化表示)模式:

客户

  • ID(整数)
  • 客户端类型 ID (int)
  • 名称(字符串)
  • 信息(jsonb)

客户类型

  • ID(整数)
  • 名称(字符串)

自定义字段定义

  • ID(整数)
  • 客户端类型 ID (int)
  • 键(字符串)
  • 标签(字符串)

在 Rails 中,ActiveRecord 神奇地将 JSONB 转换为散列,这使我能够非常轻松地使用 JSONB 来存储一组无模式的自定义字段。

例如,每种客户端类型都可以定义不同的自定义字段,然后当我向用户显示信息时,我会循环遍历定义以获取键,然后使用键从 JSONB 文档中获取数据。

我试图找出一种使用 Ecto 来完成此任务的方法,看起来我应该查看嵌入式架构(我看到了一些很好的信息 here),但是我不认为从查看它我可以在运行时为此定义自定义数量的字段,可以吗?

我只是在寻求一些建议,因为到目前为止,这是我遇到的唯一一个几乎没有立即解决的真正障碍。

再次感谢,非常感谢!

【问题讨论】:

    标签: elixir phoenix-framework ecto


    【解决方案1】:

    我可以通过稍微改变我的数据结构来解决这个问题。自定义字段现在是一个 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
    

    【讨论】:

    • 在这种情况下您将如何处理不同的数据类型?假设我有一些布尔值和其他整数值
    【解决方案2】:

    Postgrex 有一个example for a JSON extension in its Readme,它应该完全符合您的要求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-23
      • 2011-03-18
      • 2021-12-17
      • 2015-10-28
      相关资源
      最近更新 更多