Schemaless Changset Issues

So I’m running through the book Pragmatic Programmers: Building Table Views with Phoenix LiveView

I downloaded the initial project from the github: GitHub - PJUllrich/pragprog-book-tables

I’m using the zipped file at the end so that its fresh and I can make all the changes as I go through the book.

I’m at the part where you build your own schemaless changeset. I have everything that copied from the book into the 2 files sorting_form.ex and ecto_helper.ex but when I try to test the functionality of the Schemaless Changset I get this error.

SortingForm.parse(%{"sort_by" => "name", "sort_dir" => "desc"})
** (FunctionClauseError) no function clause matching in Ecto.Type.cast_fun/1    
    
    The following arguments were given to Ecto.Type.cast_fun/1:
    
        # 1
        {:parameterized, Ecto.Enum,
         %{
           on_load: %{"id" => :id, "name" => :name},
           type: :string,
           embed_as: :self,
           mappings: [id: "id", name: "name"],
           on_cast: %{"id" => :id, "name" => :name},
           on_dump: %{id: "id", name: "name"}
         }}
    
    Attempted function clauses (showing 10 out of 27):
    
        defp cast_fun(:integer)
        defp cast_fun(:float)
        defp cast_fun(:boolean)
        defp cast_fun(:map)
        defp cast_fun(:string)
        defp cast_fun(:binary)
        defp cast_fun(:bitstring)
        defp cast_fun(:id)
        defp cast_fun(:binary_id)
        defp cast_fun(:any)
        ...
        (17 clauses not shown)
    
    (ecto 3.12.5) lib/ecto/type.ex:836: Ecto.Type.cast_fun/1
    (ecto 3.12.5) lib/ecto/type.ex:833: Ecto.Type.cast/2
    (ecto 3.12.5) lib/ecto/changeset.ex:888: Ecto.Changeset.cast_field/9
    (ecto 3.12.5) lib/ecto/changeset.ex:835: Ecto.Changeset.process_param/9
    (elixir 1.18.3) lib/enum.ex:2546: Enum."-reduce/3-lists^foldl/2-0-"/3
    (ecto 3.12.5) lib/ecto/changeset.ex:792: Ecto.Changeset.cast/6
    (meow 0.1.0) lib/meow_web/forms/sorting_form.ex:15: MeowWeb.Forms.SortingForm.parse/1
    iex:2: (file)

I’m not sure if its an issue with the deps or something else. I can add in more files if that helps with this.
Thanks for your time.

This looks incorrect. This should probably be {:parameterized, {module(), term()}} based on Ecto.Type — Ecto v3.12.5

This changed in Ecto 3.12.0. It’s recommended to use Ecto.ParameterizedType.init/2 to generate that value.

iex(1)> Ecto.ParameterizedType.init(Ecto.Enum, values: [:id, :name])
{:parameterized,
 {Ecto.Enum,
  %{
    on_load: %{"id" => :id, "name" => :name},
    type: :string,
    embed_as: :self,
    mappings: [id: "id", name: "name"],
    on_dump: %{id: "id", name: "name"},
    on_cast: %{"id" => :id, "name" => :name}
  }}}
def enum(values) do
    {:parameterized, {Ecto.Enum, Ecto.Enum.init(values: values)}}
end

Thanks a lot this seemed to work well.

iex(22)> SortingForm.parse(%{sort_by: :name, sort_dir: :desc})
{:ok, %{sort_by: :name, sort_dir: :desc}}
iex(23)> SortingForm.parse(%{"sort_dir" => "asc"})
{:ok, %{sort_by: :id, sort_dir: :asc}}
iex(24)> SortingForm.parse(%{"sort_by" => "name", "sort_dir" => "desc"})
{:ok, %{sort_by: :name, sort_dir: :desc}}

Thanks for the reply I was able to use this syntax to fix the issue.

 {:parameterized, {Ecto.Enum, Ecto.Enum.init(values: values)}}

Trying what you suggested got me this error.

def enum(values) do
    Ecto.ParameterizedType.init(Ecto.Enum, values: [values])
end
SortingForm.parse(%{sort_by: :name, sort_dir: :desc})
{:error,
 #Ecto.Changeset<
   action: :insert,
   changes: %{sort_by: :name},
   errors: [
     sort_dir: {"is invalid",
      [
        type: {:parameterized,
         {Ecto.Enum,
          %{
            on_load: %{"id" => :id, "name" => :name},
            type: :string,
            on_cast: %{"id" => :id, "name" => :name},
            embed_as: :self,
            on_dump: %{id: "id", name: "name"},
            mappings: [id: "id", name: "name"]
          }}},
        validation: :inclusion,
        enum: ["id", "name"]
      ]}
   ],
   data: %{sort_by: :id, sort_dir: :asc},
   valid?: false,
   ...
 >}

Did I do something wrong? As I said I have a solution I just like to know as much as possible.