elixir - 使用ecto存储自定义信息

标签 elixir phoenix-framework ecto

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

客户

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

  • 客户类型
  • ID (int)
  • 姓名(字符串)

  • 自定义字段定义
  • ID (int)
  • 客户端类型 ID (int)
  • key (字符串)
  • 标签(字符串)

  • 在 Rails 中,ActiveRecord 神奇地将 JSONB 与散列相互转换,这使我可以使用 JSONB 非常轻松地存储一组无模式的自定义字段。

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

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

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

    再次感谢,我很感激!

    最佳答案

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

    关于elixir - 使用ecto存储自定义信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32724868/

    相关文章:

    erlang - Elixir/Erlang 中字符串的长度和大小需要解释

    elixir - Repo.update_all 之后 Ecto 中的 Updated_at

    elixir - 处理 phoenix elixir 中的模式匹配异常

    elixir - 基于 Ecto 关联查询

    elixir - Phoenix Code_Reloader 是否只重新加载 Elixir 代码?

    elixir - phx-change 后更新表单字段的值

    javascript - 如何在没有 "wrapper: false"的情况下通过 brunch 访问包装到命名空间中的函数?

    elixir - has_many,通过Ecto中的关联

    elixir - Phoenix Controller 中的预期 :action/2 to return a Plug. Conn 错误

    elixir - 将 LEFT OUTER JOIN 查询转换为 Ecto