hariharasudhan94

hariharasudhan94

How to get struct from map - elixir?

Lets say I have map like this fetching from my database

    %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => "XXXX@gmail.com", "name" => "Hariharasudhan", "password_hash" => "XXXX", "phone" => "XXXX"}

and i have struct like follow

           > @primary_key{:id, :binary_id, autogenerate: true}
      schema "users" do
        field :name, :string
        field :email, :string
        field :phone, :string
        field :password_hash, :string
      end'

What is best way to convert Map to User Struct?

note:

I need to do this convertion on each request after authentication , so I need effective way to achieve this?

Marked As Solved

hubertlepicki

hubertlepicki

I use this code.

with original version coming from:

Also Liked

manukall

manukall

That’s what Kernel — Elixir v1.20.2 does.

10
Post #2
Nicd

Nicd

This is dangerous as it doesn’t check that the keys in map_defaults actually correspond to keys of the struct. You may end up with a broken struct which is annoying to debug. What you should do is:

s = struct!(User, map_defaults)

This will ensure that keys that are in @enforce_keys must be exist and there are no keys that don’t exist in the struct. Otherwise it will raise an error. There is also Kernel.struct/2 (i.e. without exlamation mark) that will just discard unknown keys and won’t enforce @enforce_keys.

mbuhot

mbuhot

Untested, but it seems like cast and apply_changes should do what you want:

%User{} |> Ecto.Changeset.cast(map, User.__schema__(:fields)) |> Ecto.Changeset.apply_changes()

Last Post!

dubeypranav4

dubeypranav4

I think this approach is the right fit for me. It preserves Ecto’s type casting without relying on validations that feel out of place when loading from the DB. A changeset makes sense in the app-to-DB direction, but going the other way it’s redundant since the data has already passed validation (at least if Ecto is the only DB writer — otherwise falling back to a proper changeset is fine).

pry(2)> 
Ecto.Changeset.cast(struct(schema_module), params, schema_module.__schema__(:fields)) 
|> Ecto.Changeset.apply_changes()
%Mozek.V3.Orchestrator.Rule.Instance.RequestSchema{
  __meta__: #Ecto.Schema.Metadata<:built, "v3_rule_instance_requests">,
  id: 207,
  freshness_stat_id: 718,
  inserted_at: ~U[2025-08-22 11:34:45Z]
}

A utility function like this works well — it handles type casting and embeds (associations could be added similarly if needed):

@spec cast_to_struct(module(), map()) :: struct()
def cast_to_struct(schema_module, params) when is_atom(schema_module) and is_map(params) do
  unless has_changeset?(schema_module) do
    raise "Schema #{inspect(schema_module)} does not have a changeset/2 function"
  end

  fields = schema_module.__schema__(:fields) -- schema_module.__schema__(:embeds)

  struct(schema_module)
  |> Ecto.Changeset.cast(params, fields)
  |> then(fn cs ->
    Enum.reduce(schema_module.__schema__(:embeds), cs, fn embed, acc ->
      Ecto.Changeset.cast_embed(acc, embed)
    end)
  end)
  |> Ecto.Changeset.apply_changes()
end

Where Next?

Popular in Questions Top

RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

Other popular topics Top

jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
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
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement