drapermd

drapermd

Dynamic nested model in embeded field

Hello there!

I’m having a devil of a time getting a dynamic embedded schema to save in postgres.

So I started here, basically
https://github.com/elixir-ecto/ecto/pull/2113#issuecomment-412829999

But my core problem is that despite several iterations, when it goes to save it to the database, it throws

(UndefinedFunctionError) function :map.schema/1 is undefined (module :map is not available)

So in my hunt, I came across this package and it slimmed down the code, but I still have the same problem :(. It’s like ecto isn’t seeing the type update before it goes into schema. With your package the changeset automatically sets the type, which is really super nice, but for some reason I can’t get this to save to postgres:

## This is the latest iteration, of many attempts.

defmodule Geeks.Activities.Activity do
  @moduledoc false

  use Ecto.Schema
  import Ecto.Changeset
  import GatheringRole
  alias Geeks.Activities.Types

  embedded_schema do
    field :type, ActivityType
    field :title, :string
    field :max_participants, :integer
    field :next_start, :utc_datetime
    embeds_one :properties, :map
    embeds_many :rsvp, Geeks.Activities.ActivityRsvp
    embeds_many :history, Geeks.Activities.ActivityHistory do
      field :history_event, :string
      timestamps([types: :utc_datetime])
    end
    timestamps([types: :utc_datetime])
  end


  @all_fields ~w(type title max_participants next_start)a
  @required_fields ~w(type title)a
  defp properties_type(props_schema) do
    {:embed,
      %Ecto.Embedded{
        cardinality: :one,
        field: :properties,
        on_cast: &props_schema.changeset(&1, &2),
        on_replace: :update,
        owner: nil,
        related: props_schema,
        unique: true
      }}
  end

  def create_changeset(%{ properties: props } = params) do
    {:ok, props_schema} = Types.get_schema(:ttrpg)
    props_cs = EctoMorph.generate_changeset(props, props_schema)
    case props_cs.valid? do
      true ->
        changeset =
          %__MODULE__{}
          |> cast(params, @required_fields)
          |> Map.update!(:types, &Map.put(&1, :properties, properties_type(props_schema)))
          |> cast_embed(:properties)
          |> validate_required(@required_fields)
      false ->
        props_cs
    end


  end

  def create_changeset(%{} = params ) do
    create_changeset(%{params | properties: %{}})
  end

end

And elsewhere, in the context:

  def add_activity(%Gathering{ activities: activities} = gathering, activity_params \\ %{properties: %{}}) do
   changeset = Ecto.Changeset.change(gathering)
   activity = Geeks.Activities.Activity.create_changeset(activity_params)
   case activity.valid? do
     true -> changeset = Ecto.Changeset.put_embed(changeset, :activities, activities ++ [activity])
             |> Geeks.Repo.update!
     false -> {:error, activity}
   end

I did see this post: How to validate dynamic fields in embedded_schema - #4 by LostKobrakai

But it just seems like I’m missing something

I’m going to try to cross-post this to the elixir forums, but man it’s a brainweaver!

Where Next?

Popular in Questions Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New

Other popular topics Top

jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New

We're in Beta

About us Mission Statement