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

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
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
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
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
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
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
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

We're in Beta

About us Mission Statement