lorenzomar
Hi there!
I’m in the situation where I’m receiving a struct which is also an Ecto Schema (wich embedded_one/many other schemas). To be more precise it is a Commanded command.
Sometimes I may not be in control of how the command was built before dispatching it so I would implement a middleware that validate the command before and pass to the next layer only if everything is ok.
Passing the command to the changeset function doesn’t work since it is not a map (itself or the embedded structs).
Currently I implemented a changeset function like this:
defmodule MySchema do
....
def changeset(%__MODULE__{} = schema, %__MODULE__{} = attrs) do
changeset(schema, Map.from_struct(attrs))
end
def changeset(%__MODULE__{} = schema, attrs) do
# all changeset stuff: cast, validate, ...
end
end
All the embedded schemas implement a changeset like that. In this way it recursively transform a struct in a map before executing real changeset functionalities.
It works, but it seems like a lot of work.
Any suggestion? Do you know any better approach? maybe can I approach things differently?
Any help is really welcome.
Thanks!
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #phoenix_html
- #iex
- #graphql
- #ai
- #genstage
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex










Showing Posts 1 to 1- Show Best Posts
- Show All Posts (oldest first)
- Show All Posts (newest first)
LostKobrakai
What you’re running into is twofold.
Ecto.Changeset.castdoesn’t allow non map inputs. That’s by design becausecastis meant to deal with external input – as in having uncontrolled values, unknown types of value represenation and such. Stuff like json or form input. When you got a struct that’s very unlikely external input like that anymore. There are other API more suited for the job likeput_change/3orchange/2.The other part is that changeset validations only validate changes, not existing values. You can force values to become changes with e.g.
force_change/3or some other APIs can also optionally force changes on a changeset.Generally I’d however wonder why you’re validating things in the middle of handling a command and not at creation. A command should likely adhere to a contract shared between parties to be enforced at creation time.