I have a form that is backed by a table. As part of the form I have a section where I accept a key, value, and data type from the user. The idea is to build up a JSON object but allow the user to add them one by one. On the backend I want to do some validation on these key/value pairs such as ensuring the input can be cast to the data type selected, and making sure they’re not blank. I have all that working.
The problem I’m running into now is that I’d like to do something like this:
defmodule Tree do
use Ecto.Schema
schema "tree" do
embeds_one :leaf, Leaf
end
end
defmodule Leaf do
use Ecto.Schema
@primary_key false
embedded_schema do
field :leafs, :map, default: %{}
end
def changeset(schema, %{"leafs" => leafs}) do
schema
|> cast(%{"leafs" => leafs}, [:leafs])
|> validate_and_cast_custom_facts()
end
@blacklist = ["apple", "orange"]
defp validate_and_cast_custom_facts(changeset) do
validate_change changeset, :leafs, fn :leafs, {k, v} ->
if k in @blacklist do
["#{k}": "#{k} is a blacklisted key."]
else
[]
end
end
end
end
The problem is that it involves converting use input (the key from the form) into an atom in order to add it to the changeset as an error. I can’t think of a better way to do this as I’m using Changesets throughout in API responses and forms for rendering errors. Is there another way I could do this?