'Using Ecto embedded schema to validate query params and persisting them as a string in the database

I have a Ecto schema with a :string param that will persist a URI query string into the database:

defmodule Config do
  use Ecto.Schema
  import Ecto.Changeset

  schema "configs" do
    field :query_params, :string
  end
end

Even if the query string is finally saved as a string into the database I need a way to validate and encode the different params into the final string.

To do this I have created the following embedded schema:

defmodule QueryParam do
  use Ecto.Schema
  import Ecto.Changeset

  @invalid_keys ~w(name)

  @primary_key false

  embedded_schema do
    field :key, :string
    field :value, :string
  end

  def changeset(query_param, attrs) do
    query_param
    |> cast(attrs, [:key, :value])
    |> validate_required([:key, :value])
    |> validate_exclusion(:key, @invalid_keys)
  end
end

Assuming that I can use the above embedded schema into the Config schema with the following change:

defmodule Config do
  use Ecto.Schema
  import Ecto.Changeset

  schema "configs" do
    field :query_params, :string
    embeds_many :params, QueryParam
  end
end

This solution could allow me to easily generate forms with inputs_for helper but the problem is that I don't want to persist :params into the database (and virtual: true does not work with embeds_many).

I have tried defining a custom Ecto Type but I'm not sure if it's the right solution.

At the end I need the following:

  1. An easy way to generate forms for the different key -> value of the query params.
  2. A way to validate the different key -> value params.
  3. A way to encode these into a final string to be persisted into the database.

I would like to know if there is a way to model this problem with Ecto and Phoenix before pivoting to a total frontend solution with JS.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source